]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkrange.c
Change FSF Address
[~andy/gtk] / gtk / gtkrange.c
index ad6af8bd0b3829c1edac0905f5e6c61608c3fcb9..8b43a7c88439052f424827d7c75fc75738b32f94 100644 (file)
@@ -13,9 +13,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /*
 #include <stdio.h>
 #include <math.h>
 
-#include "gtkmainprivate.h"
+#include "gtkmain.h"
 #include "gtkmarshalers.h"
 #include "gtkorientableprivate.h"
 #include "gtkrange.h"
 #include "gtkscale.h"
+#include "gtkcolorscaleprivate.h"
 #include "gtkscrollbar.h"
 #include "gtkwindow.h"
 #include "gtkprivate.h"
 #include "gtkintl.h"
+#include "gtkmain.h"
 #include "gtktypebuiltins.h"
+#include "a11y/gtkrangeaccessible.h"
 
 /**
  * SECTION:gtkrange
@@ -79,12 +80,10 @@ struct _GtkRangePrivate
   gint  mouse_x;
   gint  mouse_y;
   MouseLocation      grab_location;   /* "grabbed" mouse location, OUTSIDE for no grab */
-  guint              grab_button : 8; /* 0 if none */
 
   GtkRangeStepTimer *timer;
 
   GtkAdjustment     *adjustment;
-  GtkOrientation     orientation;
   GtkSensitivityType lower_sensitivity;
   GtkSensitivityType upper_sensitivity;
 
@@ -102,7 +101,7 @@ struct _GtkRangePrivate
   GQuark             slider_detail_quark;
   GQuark             stepper_detail_quark[4];
 
-  gboolean recalc_marks;
+  GtkOrientation     orientation;
 
   gdouble  fill_level;
   gdouble *marks;
@@ -129,6 +128,7 @@ struct _GtkRangePrivate
   guint flippable              : 1;
   guint inverted               : 1;
   guint need_recalc            : 1;
+  guint recalc_marks           : 1;
   guint slider_size_fixed      : 1;
   guint trough_click_forward   : 1;  /* trough click was on the forward side of slider */
 
@@ -136,9 +136,14 @@ struct _GtkRangePrivate
   guint lower_sensitive        : 1;
   guint upper_sensitive        : 1;
 
+  /* The range has an origin, should be drawn differently. Used by GtkScale */
+  guint has_origin             : 1;
+
   /* Fill level */
   guint show_fill_level        : 1;
   guint restrict_to_fill_level : 1;
+
+  guint grab_button            : 8; /* 0 if none */
 };
 
 
@@ -374,8 +379,6 @@ gtk_range_class_init (GtkRangeClass *class)
    * @range: the #GtkRange that received the signal
    * @scroll: the type of scroll action that was performed
    * @value: the new value resulting from the scroll action
-   * @returns: %TRUE to prevent other handlers from being invoked for the
-   * signal, %FALSE to propagate the signal further
    *
    * The #GtkRange::change-value signal is emitted when a scroll action is
    * performed on a range.  It allows an application to determine the
@@ -393,6 +396,9 @@ gtk_range_class_init (GtkRangeClass *class)
    * It is not possible to use delayed update policies in an overridden
    * #GtkRange::change-value handler.
    *
+   * Returns: %TRUE to prevent other handlers from being invoked for
+   *     the signal, %FALSE to propagate the signal further
+   *
    * Since: 2.6
    */
   signals[CHANGE_VALUE] =
@@ -542,8 +548,6 @@ gtk_range_class_init (GtkRangeClass *class)
    * GtkRange:stepper-spacing:
    *
    * The spacing between the stepper buttons and thumb. Note that
-   * setting this value to anything > 0 will automatically set the
-   * trough-under-steppers style property to %TRUE as well. Also,
    * stepper-spacing won't have any effect if there are no steppers.
    */
   gtk_widget_class_install_style_property (widget_class,
@@ -575,9 +579,7 @@ gtk_range_class_init (GtkRangeClass *class)
    * GtkRange:trough-under-steppers:
    *
    * Whether to draw the trough across the full length of the range or
-   * to exclude the steppers and their spacing. Note that setting the
-   * #GtkRange:stepper-spacing style property to any value > 0 will
-   * automatically enable trough-under-steppers too.
+   * to exclude the steppers and their spacing.
    *
    * Since: 2.10
    */
@@ -603,6 +605,8 @@ gtk_range_class_init (GtkRangeClass *class)
                                                               GTK_PARAM_READABLE));
 
   g_type_class_add_private (class, sizeof (GtkRangePrivate));
+
+  gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_RANGE_ACCESSIBLE);
 }
 
 static void
@@ -734,6 +738,7 @@ gtk_range_init (GtkRange *range)
   priv->upper_sensitivity = GTK_SENSITIVITY_AUTO;
   priv->lower_sensitive = TRUE;
   priv->upper_sensitive = TRUE;
+  priv->has_origin = FALSE;
   priv->show_fill_level = FALSE;
   priv->restrict_to_fill_level = TRUE;
   priv->fill_level = G_MAXDOUBLE;
@@ -1618,7 +1623,7 @@ modify_allocation_for_window_grip (GtkWidget     *widget,
     translated_rect = *allocation;
   else
     {
-      gtk_widget_translate_coordinates (gtk_widget_get_parent (widget),
+      gtk_widget_translate_coordinates (parent,
                                         window,
                                         allocation->x, allocation->y,
                                         &x, &y);
@@ -1629,7 +1634,7 @@ modify_allocation_for_window_grip (GtkWidget     *widget,
     }
 
   /* If the stepper button intersects the window resize grip.. */
-  if (gdk_rectangle_intersect (&grip_rect, &translated_rect, NULL))
+  if (gdk_rectangle_intersect (&grip_rect, &translated_rect, &grip_rect))
     {
       if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
         {
@@ -1842,7 +1847,6 @@ _gtk_range_update_context_for_stepper (GtkRange        *range,
     }
 
   gtk_style_context_set_junction_sides (context, sides);
-  gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON);
 }
 
 static void
@@ -1851,17 +1855,17 @@ draw_stepper (GtkRange     *range,
               cairo_t      *cr,
               GtkArrowType  arrow_type,
               gboolean      clicked,
-              gboolean      prelighted)
+              gboolean      prelighted,
+              GtkStateFlags state)
 {
   GtkRangePrivate *priv = range->priv;
   GtkAllocation allocation;
-  GtkStateFlags state = 0;
   GtkStyleContext *context;
   GtkWidget *widget = GTK_WIDGET (range);
   gfloat arrow_scaling;
   GdkRectangle *rect;
-  gint arrow_x;
-  gint arrow_y;
+  gdouble arrow_x;
+  gdouble arrow_y;
   gdouble arrow_size, angle;
   gboolean arrow_sensitive;
 
@@ -1899,8 +1903,12 @@ draw_stepper (GtkRange     *range,
       arrow_sensitive = priv->lower_sensitive;
     }
 
-  if (!gtk_widget_is_sensitive (GTK_WIDGET (range)) || !arrow_sensitive)
-    state = GTK_STATE_FLAG_INSENSITIVE;
+  state &= ~(GTK_STATE_FLAG_ACTIVE | GTK_STATE_FLAG_PRELIGHT);
+
+  if ((state & GTK_STATE_FLAG_INSENSITIVE) || !arrow_sensitive)
+    {
+      state |= GTK_STATE_FLAG_INSENSITIVE;
+    }
   else
     {
       if (clicked)
@@ -1912,9 +1920,33 @@ draw_stepper (GtkRange     *range,
   context = gtk_widget_get_style_context (widget);
 
   gtk_style_context_save (context);
-  _gtk_range_update_context_for_stepper (range, context, stepper);
+
+  /* don't set juction sides on scrollbar steppers */
+  if (gtk_style_context_has_class (context, GTK_STYLE_CLASS_SCROLLBAR))
+    gtk_style_context_set_junction_sides (context, GTK_JUNCTION_NONE);
+  else
+    _gtk_range_update_context_for_stepper (range, context, stepper);
+
+  gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON);
   gtk_style_context_set_state (context, state);
 
+  switch (arrow_type)
+    {
+    case GTK_ARROW_RIGHT:
+      gtk_style_context_add_class (context, GTK_STYLE_CLASS_RIGHT);
+      break;
+    case GTK_ARROW_DOWN:
+      gtk_style_context_add_class (context, GTK_STYLE_CLASS_BOTTOM);
+      break;
+    case GTK_ARROW_LEFT:
+      gtk_style_context_add_class (context, GTK_STYLE_CLASS_LEFT);
+      break;
+    case GTK_ARROW_UP:
+    default:
+      gtk_style_context_add_class (context, GTK_STYLE_CLASS_TOP);
+      break;
+    }
+
   gtk_render_background (context, cr,
                          rect->x, rect->y,
                          rect->width, rect->height);
@@ -1972,12 +2004,12 @@ gtk_range_draw (GtkWidget *widget,
 {
   GtkRange *range = GTK_RANGE (widget);
   GtkRangePrivate *priv = range->priv;
-  gboolean sensitive;
-  GtkStateFlags state = 0;
+  GtkStateFlags widget_state;
   gint focus_line_width = 0;
   gint focus_padding = 0;
   gboolean touchscreen;
   gboolean draw_trough = TRUE;
+  gboolean draw_slider = TRUE;
   GtkStyleContext *context;
 
   context = gtk_widget_get_style_context (widget);
@@ -1987,7 +2019,15 @@ gtk_range_draw (GtkWidget *widget,
 
   if (GTK_IS_SCALE (widget) &&
       gtk_adjustment_get_upper (priv->adjustment) == gtk_adjustment_get_lower (priv->adjustment))
-    draw_trough = FALSE;
+    {
+      draw_trough = TRUE;
+      draw_slider = FALSE;
+    }
+  if (GTK_IS_COLOR_SCALE (widget))
+    {
+      draw_trough = FALSE;
+      draw_slider = TRUE;
+    }
 
   if (gtk_widget_get_can_focus (GTK_WIDGET (range)))
     gtk_widget_style_get (GTK_WIDGET (range),
@@ -2003,7 +2043,7 @@ gtk_range_draw (GtkWidget *widget,
   gtk_range_calc_marks (range);
   gtk_range_calc_layout (range, gtk_adjustment_get_value (priv->adjustment));
 
-  sensitive = gtk_widget_is_sensitive (widget);
+  widget_state = gtk_widget_get_state_flags (widget);
 
   /* Just to be confusing, we draw the trough for the whole
    * range rectangle, not the trough rectangle (the trough
@@ -2032,14 +2072,6 @@ gtk_range_draw (GtkWidget *widget,
                             "stepper-spacing",       &stepper_spacing,
                             NULL);
 
-      gtk_style_context_save (context);
-
-      if (!sensitive)
-        gtk_style_context_set_state (context, GTK_STATE_FLAG_INSENSITIVE);
-
-      if (stepper_spacing > 0)
-        trough_under_steppers = FALSE;
-
       if (!trough_under_steppers)
         {
           gint offset  = 0;
@@ -2087,44 +2119,82 @@ gtk_range_draw (GtkWidget *widget,
 
       if (draw_trough)
         {
-          gint trough_change_pos_x = width;
-          gint trough_change_pos_y = height;
-
-          if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
-            trough_change_pos_x = (priv->slider.x +
-                                   priv->slider.width / 2 -
-                                   x);
-          else
-            trough_change_pos_y = (priv->slider.y +
-                                   priv->slider.height / 2 -
-                                   y);
-
-          /* FIXME: was trough-upper and trough-lower really used,
-           * in that case, it should still be exposed somehow.
-           */
-          gtk_render_background (context, cr, x, y,
-                                 trough_change_pos_x,
-                                 trough_change_pos_y);
+          if (!priv->has_origin)
+            {
+              gtk_render_background (context, cr,
+                                     x, y, width, height);
 
-          if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
-            trough_change_pos_y = 0;
+              gtk_render_frame (context, cr,
+                                x, y, width, height);
+            }
           else
-            trough_change_pos_x = 0;
-
-          gtk_render_background (context, cr,
-                                 x + trough_change_pos_x, y + trough_change_pos_y,
-                                 width - trough_change_pos_x,
-                                 height - trough_change_pos_y);
-
-          gtk_render_frame (context, cr,
-                            x, y, width, height);
-        }
-      else
-        {
-          gtk_render_background (context, cr,
-                                 x, y, width, height);
-          gtk_render_frame (context, cr,
-                            x, y, width, height);
+            {
+              gboolean is_rtl = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
+
+              gint trough_change_pos_x = width;
+              gint trough_change_pos_y = height;
+
+              if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+                trough_change_pos_x = (priv->slider.x +
+                                       priv->slider.width / 2 -
+                                       x);
+              else
+                trough_change_pos_y = (priv->slider.y +
+                                       priv->slider.height / 2 -
+                                       y);
+
+              gtk_style_context_save (context);
+              if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+                {
+                  gtk_style_context_add_class (context, GTK_STYLE_CLASS_LEFT);
+
+                  if (!is_rtl)
+                    gtk_style_context_add_class (context, GTK_STYLE_CLASS_HIGHLIGHT);
+                }
+              else
+                gtk_style_context_add_class (context, GTK_STYLE_CLASS_TOP);
+
+              gtk_render_background (context, cr, x, y,
+                                     trough_change_pos_x,
+                                     trough_change_pos_y);
+
+              gtk_render_frame (context, cr, x, y,
+                                trough_change_pos_x,
+                                trough_change_pos_y);
+
+              gtk_style_context_restore (context);
+
+              if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+                trough_change_pos_y = 0;
+              else
+                trough_change_pos_x = 0;
+
+              gtk_style_context_save (context);
+              if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+                {
+                  gtk_style_context_add_class (context, GTK_STYLE_CLASS_RIGHT);
+
+                  if (is_rtl)
+                    gtk_style_context_add_class (context, GTK_STYLE_CLASS_HIGHLIGHT);
+                }
+              else
+                {
+                  gtk_style_context_add_class (context, GTK_STYLE_CLASS_BOTTOM);
+                  gtk_style_context_add_class (context, GTK_STYLE_CLASS_HIGHLIGHT);
+                }
+
+              gtk_render_background (context, cr,
+                                     x + trough_change_pos_x, y + trough_change_pos_y,
+                                     width - trough_change_pos_x,
+                                     height - trough_change_pos_y);
+
+              gtk_render_frame (context, cr,
+                                x + trough_change_pos_x, y + trough_change_pos_y,
+                                width - trough_change_pos_x,
+                                height - trough_change_pos_y);
+
+              gtk_style_context_restore (context);
+            }
         }
 
       gtk_style_context_restore (context);
@@ -2189,40 +2259,34 @@ gtk_range_draw (GtkWidget *widget,
           gtk_style_context_restore (context);
         }
 
-      gtk_style_context_restore (context);
-
-      if (sensitive && gtk_widget_has_focus (widget))
+      if (!(widget_state & GTK_STATE_FLAG_INSENSITIVE) && gtk_widget_has_visible_focus (widget))
         {
-          gtk_style_context_save (context);
-          gtk_style_context_set_state (context,
-                                       gtk_widget_get_state_flags (widget));
-
           gtk_render_focus (context, cr,
                             priv->range_rect.x,
                             priv->range_rect.y,
                             priv->range_rect.width,
                             priv->range_rect.height);
-
-          gtk_style_context_restore (context);
         }
     }
 
   cairo_restore (cr);
 
-  if (!sensitive)
-    state = GTK_STATE_FLAG_INSENSITIVE;
-  else if (!touchscreen && priv->mouse_location == MOUSE_SLIDER)
-    state = GTK_STATE_FLAG_PRELIGHT;
+  if (draw_slider)
+    {
+      GtkStateFlags state = widget_state;
 
-  if (priv->grab_location == MOUSE_SLIDER)
-    state |= GTK_STATE_FLAG_ACTIVE;
+      state &= ~(GTK_STATE_FLAG_PRELIGHT | GTK_STATE_FLAG_ACTIVE);
 
-  cairo_save (cr);
-  gdk_cairo_rectangle (cr, &priv->slider);
-  cairo_clip (cr);
+      if (!touchscreen && priv->mouse_location == MOUSE_SLIDER && !(state & GTK_STATE_FLAG_INSENSITIVE))
+        state |= GTK_STATE_FLAG_PRELIGHT;
+
+      if (priv->grab_location == MOUSE_SLIDER)
+        state |= GTK_STATE_FLAG_ACTIVE;
+
+      cairo_save (cr);
+      gdk_cairo_rectangle (cr, &priv->slider);
+      cairo_clip (cr);
 
-  if (draw_trough)
-    {
       gtk_style_context_save (context);
       gtk_style_context_add_class (context, GTK_STYLE_CLASS_SLIDER);
       gtk_style_context_set_state (context, state);
@@ -2235,33 +2299,37 @@ gtk_range_draw (GtkWidget *widget,
                          priv->orientation);
 
       gtk_style_context_restore (context);
-    }
 
-  cairo_restore (cr);
+      cairo_restore (cr);
+    }
 
   if (priv->has_stepper_a)
     draw_stepper (range, STEPPER_A, cr,
                   priv->orientation == GTK_ORIENTATION_VERTICAL ? GTK_ARROW_UP : GTK_ARROW_LEFT,
                   priv->grab_location == MOUSE_STEPPER_A,
-                  !touchscreen && priv->mouse_location == MOUSE_STEPPER_A);
+                  !touchscreen && priv->mouse_location == MOUSE_STEPPER_A,
+                  widget_state);
 
   if (priv->has_stepper_b)
     draw_stepper (range, STEPPER_B, cr,
                   priv->orientation == GTK_ORIENTATION_VERTICAL ? GTK_ARROW_DOWN : GTK_ARROW_RIGHT,
                   priv->grab_location == MOUSE_STEPPER_B,
-                  !touchscreen && priv->mouse_location == MOUSE_STEPPER_B);
+                  !touchscreen && priv->mouse_location == MOUSE_STEPPER_B,
+                  widget_state);
 
   if (priv->has_stepper_c)
     draw_stepper (range, STEPPER_C, cr,
                   priv->orientation == GTK_ORIENTATION_VERTICAL ? GTK_ARROW_UP : GTK_ARROW_LEFT,
                   priv->grab_location == MOUSE_STEPPER_C,
-                  !touchscreen && priv->mouse_location == MOUSE_STEPPER_C);
+                  !touchscreen && priv->mouse_location == MOUSE_STEPPER_C,
+                  widget_state);
 
   if (priv->has_stepper_d)
     draw_stepper (range, STEPPER_D, cr,
                   priv->orientation == GTK_ORIENTATION_VERTICAL ? GTK_ARROW_DOWN : GTK_ARROW_RIGHT,
                   priv->grab_location == MOUSE_STEPPER_D,
-                  !touchscreen && priv->mouse_location == MOUSE_STEPPER_D);
+                  !touchscreen && priv->mouse_location == MOUSE_STEPPER_D,
+                  widget_state);
 
   return FALSE;
 }
@@ -2277,15 +2345,11 @@ range_grab_add (GtkRange      *range,
   if (device == priv->grab_device)
     return;
 
-  if (priv->grab_device != NULL)
-    {
-      g_warning ("GtkRange already had a grab device, releasing device grab");
-      gtk_device_grab_remove (GTK_WIDGET (range), priv->grab_device);
-    }
-
-  /* we don't actually gdk_grab, since a button is down */
-  gtk_device_grab_add (GTK_WIDGET (range), device, TRUE);
-
+  /* Don't perform any GDK/GTK+ grab here. Since a button
+   * is down, there's an ongoing implicit grab on
+   * priv->event_window, which pretty much guarantees this
+   * is the only widget receiving the pointer events.
+   */
   priv->grab_location = location;
   priv->grab_button = button;
   priv->grab_device = device;
@@ -2330,13 +2394,13 @@ range_get_scroll_for_grab (GtkRange      *range)
     case MOUSE_STEPPER_C:
       switch (priv->grab_button)
         {
-        case 1:
+        case GDK_BUTTON_PRIMARY:
           return invert ? GTK_SCROLL_STEP_FORWARD : GTK_SCROLL_STEP_BACKWARD;
           break;
-        case 2:
+        case GDK_BUTTON_MIDDLE:
           return invert ? GTK_SCROLL_PAGE_FORWARD : GTK_SCROLL_PAGE_BACKWARD;
           break;
-        case 3:
+        case GDK_BUTTON_SECONDARY:
           return invert ? GTK_SCROLL_END : GTK_SCROLL_START;
           break;
         }
@@ -2347,13 +2411,13 @@ range_get_scroll_for_grab (GtkRange      *range)
     case MOUSE_STEPPER_D:
       switch (priv->grab_button)
         {
-        case 1:
+        case GDK_BUTTON_PRIMARY:
           return invert ? GTK_SCROLL_STEP_BACKWARD : GTK_SCROLL_STEP_FORWARD;
           break;
-        case 2:
+        case GDK_BUTTON_MIDDLE:
           return invert ? GTK_SCROLL_PAGE_BACKWARD : GTK_SCROLL_PAGE_FORWARD;
           break;
-        case 3:
+        case GDK_BUTTON_SECONDARY:
           return invert ? GTK_SCROLL_START : GTK_SCROLL_END;
           break;
        }
@@ -2478,8 +2542,18 @@ gtk_range_button_press (GtkWidget      *widget,
   if (gtk_range_update_mouse_location (range))
     gtk_widget_queue_draw (widget);
 
+  if (priv->mouse_location == MOUSE_SLIDER &&
+      gdk_event_triggers_context_menu ((GdkEvent *)event))
+    {
+      gboolean handled;
+
+      g_signal_emit_by_name (widget, "popup-menu", &handled);
+
+      return TRUE;
+    }
+
   if (priv->mouse_location == MOUSE_TROUGH  &&
-      event->button == 1)
+      event->button == GDK_BUTTON_PRIMARY)
     {
       /* button 1 steps by page increment, as with button 2 on a stepper
        */
@@ -2503,7 +2577,9 @@ gtk_range_button_press (GtkWidget      *widget,
             priv->mouse_location == MOUSE_STEPPER_B ||
             priv->mouse_location == MOUSE_STEPPER_C ||
             priv->mouse_location == MOUSE_STEPPER_D) &&
-           (event->button == 1 || event->button == 2 || event->button == 3))
+           (event->button == GDK_BUTTON_PRIMARY ||
+            event->button == GDK_BUTTON_MIDDLE ||
+            event->button == GDK_BUTTON_SECONDARY))
     {
       GtkAllocation allocation;
       GdkRectangle *stepper_area;
@@ -2527,7 +2603,7 @@ gtk_range_button_press (GtkWidget      *widget,
       return TRUE;
     }
   else if ((priv->mouse_location == MOUSE_TROUGH &&
-            event->button == 2) ||
+            event->button == GDK_BUTTON_MIDDLE) ||
            priv->mouse_location == MOUSE_SLIDER)
     {
       gboolean need_value_update = FALSE;
@@ -2537,7 +2613,7 @@ gtk_range_button_press (GtkWidget      *widget,
        * On button 2 press, we warp the slider to mouse position,
        * then begin the slider drag.
        */
-      if (event->button == 2)
+      if (event->button == GDK_BUTTON_MIDDLE)
         {
           gdouble slider_low_value, slider_high_value, new_value;
           
@@ -3210,9 +3286,6 @@ gtk_range_get_props (GtkRange  *range,
                        "arrow-displacement-y", &tmp_arrow_displacement_y,
                         NULL);
 
-  if (tmp_stepper_spacing > 0)
-    tmp_trough_under_steppers = FALSE;
-
   if (gtk_widget_get_can_focus (GTK_WIDGET (range)))
     {
       gint focus_line_width;
@@ -4043,6 +4116,19 @@ gtk_range_remove_step_timer (GtkRange *range)
     }
 }
 
+void
+_gtk_range_set_has_origin (GtkRange *range,
+                           gboolean  has_origin)
+{
+  range->priv->has_origin = has_origin;
+}
+
+gboolean
+_gtk_range_get_has_origin (GtkRange *range)
+{
+  return range->priv->has_origin;
+}
+
 void
 _gtk_range_set_stop_values (GtkRange *range,
                             gdouble  *values,