]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtktextview.c
gtk: Add gtk_widget_queue_draw_region()
[~andy/gtk] / gtk / gtktextview.c
index dcf2f656f2e4d3f6b684670f97802a032b959206..3c28fdebb0dd37c0fccfa466d7b0c45579fe4100 100644 (file)
@@ -40,7 +40,6 @@
 #include "gtkseparatormenuitem.h"
 #include "gtksettings.h"
 #include "gtkstock.h"
-#include "gtksizerequest.h"
 #include "gtktextbufferrichtext.h"
 #include "gtktextdisplay.h"
 #include "gtktextview.h"
@@ -141,7 +140,7 @@ struct _GtkTextViewPrivate
    * FIXME: This could be done in a simpler way by 
    * consulting the above width/height of the buffer + some
    * padding values, however all of this request code needs
-   * to be changed to use GtkSizeRequestIface and deserves
+   * to be changed to use GtkWidget     Iface and deserves
    * more attention.
    */
   GtkRequisition cached_size_request;
@@ -261,7 +260,6 @@ enum
   PROP_IM_MODULE
 };
 
-static void gtk_text_view_destroy              (GtkObject        *object);
 static void gtk_text_view_finalize             (GObject          *object);
 static void gtk_text_view_set_property         (GObject         *object,
                                                guint            prop_id,
@@ -271,6 +269,7 @@ static void gtk_text_view_get_property         (GObject         *object,
                                                guint            prop_id,
                                                GValue          *value,
                                                GParamSpec      *pspec);
+static void gtk_text_view_destroy              (GtkWidget        *widget);
 static void gtk_text_view_size_request         (GtkWidget        *widget,
                                                 GtkRequisition   *requisition);
 static void gtk_text_view_size_allocate        (GtkWidget        *widget,
@@ -302,9 +301,10 @@ static gint gtk_text_view_focus_out_event      (GtkWidget        *widget,
                                                 GdkEventFocus    *event);
 static gint gtk_text_view_motion_event         (GtkWidget        *widget,
                                                 GdkEventMotion   *event);
-static gint gtk_text_view_expose_event         (GtkWidget        *widget,
-                                                GdkEventExpose   *expose);
-static void gtk_text_view_draw_focus           (GtkWidget        *widget);
+static gint gtk_text_view_draw                 (GtkWidget        *widget,
+                                                cairo_t          *cr);
+static void gtk_text_view_draw_focus           (GtkWidget        *widget,
+                                                cairo_t          *cr);
 static gboolean gtk_text_view_focus            (GtkWidget        *widget,
                                                 GtkDirectionType  direction);
 static void gtk_text_view_move_focus           (GtkWidget        *widget,
@@ -563,7 +563,6 @@ static void
 gtk_text_view_class_init (GtkTextViewClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-  GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
   GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
   GtkBindingSet *binding_set;
@@ -572,10 +571,9 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
    */
   gobject_class->set_property = gtk_text_view_set_property;
   gobject_class->get_property = gtk_text_view_get_property;
-
-  object_class->destroy = gtk_text_view_destroy;
   gobject_class->finalize = gtk_text_view_finalize;
 
+  widget_class->destroy = gtk_text_view_destroy;
   widget_class->realize = gtk_text_view_realize;
   widget_class->unrealize = gtk_text_view_unrealize;
   widget_class->style_set = gtk_text_view_style_set;
@@ -592,7 +590,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
   widget_class->focus_in_event = gtk_text_view_focus_in_event;
   widget_class->focus_out_event = gtk_text_view_focus_out_event;
   widget_class->motion_notify_event = gtk_text_view_motion_event;
-  widget_class->expose_event = gtk_text_view_expose_event;
+  widget_class->draw = gtk_text_view_draw;
   widget_class->focus = gtk_text_view_focus;
 
   /* need to override the base class function via override_class_handler,
@@ -1090,7 +1088,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
    */
   signals[SELECT_ALL] =
     g_signal_new_class_handler (I_("select-all"),
-                                G_OBJECT_CLASS_TYPE (object_class),
+                                G_OBJECT_CLASS_TYPE (gobject_class),
                                 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                                 G_CALLBACK (gtk_text_view_select_all),
                                 NULL, NULL,
@@ -1109,7 +1107,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
    */ 
   signals[TOGGLE_CURSOR_VISIBLE] =
     g_signal_new_class_handler (I_("toggle-cursor-visible"),
-                                G_OBJECT_CLASS_TYPE (object_class),
+                                G_OBJECT_CLASS_TYPE (gobject_class),
                                 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                                 G_CALLBACK (gtk_text_view_toggle_cursor_visible),
                                 NULL, NULL,
@@ -1132,7 +1130,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
    */
   signals[PREEDIT_CHANGED] =
     g_signal_new_class_handler (I_("preedit-changed"),
-                                G_OBJECT_CLASS_TYPE (object_class),
+                                G_OBJECT_CLASS_TYPE (gobject_class),
                                 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                                 NULL,
                                 NULL, NULL,
@@ -3009,12 +3007,12 @@ gtk_text_view_remove_validate_idles (GtkTextView *text_view)
 }
 
 static void
-gtk_text_view_destroy (GtkObject *object)
+gtk_text_view_destroy (GtkWidget *widget)
 {
   GtkTextView *text_view;
   GtkTextViewPrivate *priv;
 
-  text_view = GTK_TEXT_VIEW (object);
+  text_view = GTK_TEXT_VIEW (widget);
   priv = text_view->priv;
 
   gtk_text_view_remove_validate_idles (text_view);
@@ -3033,7 +3031,7 @@ gtk_text_view_destroy (GtkObject *object)
       priv->im_spot_idle = 0;
     }
 
-  GTK_OBJECT_CLASS (gtk_text_view_parent_class)->destroy (object);
+  GTK_WIDGET_CLASS (gtk_text_view_parent_class)->destroy (widget);
 }
 
 static void
@@ -3309,13 +3307,9 @@ gtk_text_view_size_request (GtkWidget      *widget,
           GtkRequisition child_req;
           GtkRequisition old_req;
 
-          gtk_size_request_get_size (GTK_SIZE_REQUEST (child->widget),
-                                     &old_req, NULL);
+          gtk_widget_get_preferred_size (child->widget, &old_req, NULL);
 
-          gtk_widget_size_request (child->widget, &child_req);
-
-          gtk_size_request_get_size (GTK_SIZE_REQUEST (child->widget),
-                                     &child_req, NULL);
+          gtk_widget_get_preferred_size (child->widget, &child_req, NULL);
 
           /* Invalidate layout lines if required */
           if (priv->layout &&
@@ -3327,8 +3321,9 @@ gtk_text_view_size_request (GtkWidget      *widget,
       else
         {
           GtkRequisition child_req;
-          
-          gtk_widget_size_request (child->widget, &child_req);
+
+          gtk_widget_get_preferred_size (child->widget,
+                                         &child_req, NULL);
         }
 
       tmp_list = g_slist_next (tmp_list);
@@ -3360,8 +3355,7 @@ gtk_text_view_compute_child_allocation (GtkTextView      *text_view,
   allocation->x = vc->from_left_of_buffer - text_view->priv->xoffset;
   allocation->y = buffer_y - text_view->priv->yoffset;
 
-  gtk_size_request_get_size (GTK_SIZE_REQUEST (vc->widget),
-                             &req, NULL);
+  gtk_widget_get_preferred_size (vc->widget, &req, NULL);
   allocation->width = req.width;
   allocation->height = req.height;
 }
@@ -3443,7 +3437,7 @@ gtk_text_view_allocate_children (GtkTextView *text_view)
            * get in the way. Invalidating the layout around the anchor
            * achieves this.
           */ 
-         if (GTK_WIDGET_ALLOC_NEEDED (child->widget))
+         if (_gtk_widget_get_alloc_needed (child->widget))
            {
              GtkTextIter end = child_loc;
              gtk_text_iter_forward_char (&end);
@@ -3462,8 +3456,7 @@ gtk_text_view_allocate_children (GtkTextView *text_view)
           allocation.x = child->x;
           allocation.y = child->y;
 
-          gtk_size_request_get_size (GTK_SIZE_REQUEST (child->widget),
-                                     &child_req, NULL);
+          gtk_widget_get_preferred_size (child->widget, &child_req, NULL);
 
           allocation.width = child_req.width;
           allocation.height = child_req.height;
@@ -3997,10 +3990,9 @@ gtk_text_view_realize (GtkWidget *widget)
   attributes.height = allocation.height;
   attributes.wclass = GDK_INPUT_OUTPUT;
   attributes.visual = gtk_widget_get_visual (widget);
-  attributes.colormap = gtk_widget_get_colormap (widget);
   attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK;
 
-  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
 
   window = gdk_window_new (gtk_widget_get_parent_window (widget),
                            &attributes, attributes_mask);
@@ -4216,7 +4208,7 @@ set_invisible_cursor (GdkWindow *window)
   GdkDisplay *display;
   GdkCursor *cursor;
 
-  display = gdk_drawable_get_display (window);
+  display = gdk_window_get_display (window);
   cursor = gdk_cursor_new_for_display (display, GDK_BLANK_CURSOR);
  
   gdk_window_set_cursor (window, cursor);
@@ -4783,8 +4775,7 @@ gtk_text_view_motion_event (GtkWidget *widget, GdkEventMotion *event)
 
 static void
 gtk_text_view_paint (GtkWidget      *widget,
-                     GdkRectangle   *area,
-                     GdkEventExpose *event)
+                     cairo_t        *cr)
 {
   GtkTextView *text_view;
   GtkTextViewPrivate *priv;
@@ -4818,24 +4809,25 @@ gtk_text_view_paint (GtkWidget      *widget,
 #endif
 
   child_exposes = NULL;
+
+  cairo_save (cr);
+  cairo_translate (cr, -priv->xoffset, -priv->yoffset);
+
   gtk_text_layout_draw (priv->layout,
                         widget,
-                        priv->text_window->bin_window,
-                       NULL,
-                        priv->xoffset,
-                        priv->yoffset,
-                        area->x, area->y,
-                        area->width, area->height,
+                        cr,
                         &child_exposes);
 
+  cairo_restore (cr);
+
   tmp_list = child_exposes;
   while (tmp_list != NULL)
     {
       GtkWidget *child = tmp_list->data;
   
-      gtk_container_propagate_expose (GTK_CONTAINER (text_view),
-                                      child,
-                                      event);
+      gtk_container_propagate_draw (GTK_CONTAINER (text_view),
+                                    child,
+                                    cr);
 
       g_object_unref (child);
       
@@ -4845,21 +4837,27 @@ gtk_text_view_paint (GtkWidget      *widget,
   g_list_free (child_exposes);
 }
 
-static gint
-gtk_text_view_expose_event (GtkWidget *widget, GdkEventExpose *event)
+static gboolean
+gtk_text_view_draw (GtkWidget *widget,
+                    cairo_t   *cr)
 {
   GSList *tmp_list;
+  GdkWindow *window;
   
-  if (event->window == gtk_text_view_get_window (GTK_TEXT_VIEW (widget),
-                                                 GTK_TEXT_WINDOW_TEXT))
+  if (gtk_cairo_should_draw_window (cr, gtk_widget_get_window (widget)))
+    gtk_text_view_draw_focus (widget, cr);
+
+  window = gtk_text_view_get_window (GTK_TEXT_VIEW (widget),
+                                     GTK_TEXT_WINDOW_TEXT);
+  if (gtk_cairo_should_draw_window (cr, window))
     {
       DV(g_print (">Exposed ("G_STRLOC")\n"));
-      gtk_text_view_paint (widget, &event->area, event);
+      cairo_save (cr);
+      gtk_cairo_transform_to_window (cr, widget, window);
+      gtk_text_view_paint (widget, cr);
+      cairo_restore (cr);
     }
 
-  if (event->window == gtk_widget_get_window (widget))
-    gtk_text_view_draw_focus (widget);
-
   /* Propagate exposes to all unanchored children. 
    * Anchored children are handled in gtk_text_view_paint(). 
    */
@@ -4868,13 +4866,13 @@ gtk_text_view_expose_event (GtkWidget *widget, GdkEventExpose *event)
     {
       GtkTextViewChild *vc = tmp_list->data;
 
-      /* propagate_expose checks that event->window matches
+      /* propagate_draw checks that event->window matches
        * child->window
        */
       if (!vc->anchor)
-        gtk_container_propagate_expose (GTK_CONTAINER (widget),
-                                        vc->widget,
-                                        event);
+        gtk_container_propagate_draw (GTK_CONTAINER (widget),
+                                      vc->widget,
+                                      cr);
       
       tmp_list = tmp_list->next;
     }
@@ -4883,10 +4881,9 @@ gtk_text_view_expose_event (GtkWidget *widget, GdkEventExpose *event)
 }
 
 static void
-gtk_text_view_draw_focus (GtkWidget *widget)
+gtk_text_view_draw_focus (GtkWidget *widget,
+                          cairo_t   *cr)
 {
-  GtkAllocation allocation;
-  GdkWindow *window;
   gboolean interior_focus;
 
   /* We clear the focus if we are in interior focus mode. */
@@ -4894,24 +4891,14 @@ gtk_text_view_draw_focus (GtkWidget *widget)
                        "interior-focus", &interior_focus,
                        NULL);
   
-  if (gtk_widget_is_drawable (widget))
-    {
-      window = gtk_widget_get_window (widget);
-
-      if (gtk_widget_has_focus (widget) && !interior_focus)
-        {
-          gtk_widget_get_allocation (widget, &allocation);
-          gtk_paint_focus (gtk_widget_get_style (widget),
-                           window,
-                           gtk_widget_get_state (widget),
-                           NULL, widget, "textview",
-                           0, 0,
-                           allocation.width, allocation.height);
-        }
-      else
-        {
-          gdk_window_clear (window);
-        }
+  if (gtk_widget_has_focus (widget) && !interior_focus)
+    {          
+      gtk_paint_focus (gtk_widget_get_style (widget), cr,
+                       gtk_widget_get_state (widget),
+                       widget, "textview",
+                       0, 0,
+                       gtk_widget_get_allocated_width (widget),
+                       gtk_widget_get_allocated_height (widget));
     }
 }
 
@@ -6295,21 +6282,20 @@ drag_scan_timeout (gpointer data)
   GtkTextView *text_view;
   GtkTextViewPrivate *priv;
   GtkTextIter newplace;
-  gint x, y, width, height;
+  gint x, y;
   gdouble pointer_xoffset, pointer_yoffset;
 
   text_view = GTK_TEXT_VIEW (data);
   priv = text_view->priv;
 
   get_iter_at_pointer (text_view, priv->dnd_device, &newplace, &x, &y);
-  gdk_drawable_get_size (priv->text_window->bin_window, &width, &height);
 
   gtk_text_buffer_move_mark (get_buffer (text_view),
                              priv->dnd_mark,
                              &newplace);
 
-  pointer_xoffset = (gdouble) x / width;
-  pointer_yoffset = (gdouble) y / height;
+  pointer_xoffset = (gdouble) x / gdk_window_get_width (priv->text_window->bin_window);
+  pointer_yoffset = (gdouble) y / gdk_window_get_height (priv->text_window->bin_window);
 
   if (check_scroll (pointer_xoffset, priv->hadjustment) ||
       check_scroll (pointer_yoffset, priv->vadjustment))
@@ -6900,25 +6886,21 @@ drag_begin_cb (GtkWidget      *widget,
                GdkDragContext *context,
                gpointer        data)
 {
-  GtkTextView   *text_view = GTK_TEXT_VIEW (widget);
-  GtkTextBuffer *buffer = gtk_text_view_get_buffer (text_view);
-  GtkTextIter    start;
-  GtkTextIter    end;
-  GdkPixmap     *pixmap = NULL;
+  GtkTextView     *text_view = GTK_TEXT_VIEW (widget);
+  GtkTextBuffer   *buffer = gtk_text_view_get_buffer (text_view);
+  GtkTextIter      start;
+  GtkTextIter      end;
+  cairo_surface_t *surface = NULL;
 
   g_signal_handlers_disconnect_by_func (widget, drag_begin_cb, NULL);
 
   if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
-    pixmap = _gtk_text_util_create_rich_drag_icon (widget, buffer, &start, &end);
+    surface = _gtk_text_util_create_rich_drag_icon (widget, buffer, &start, &end);
 
-  if (pixmap)
+  if (surface)
     {
-      gtk_drag_set_icon_pixmap (context,
-                                gdk_drawable_get_colormap (pixmap),
-                                pixmap,
-                                NULL,
-                                -2, -2);
-      g_object_unref (pixmap);
+      gtk_drag_set_icon_surface (context, surface);
+      cairo_surface_destroy (surface);
     }
   else
     {
@@ -7426,11 +7408,11 @@ gtk_text_view_set_scroll_adjustments (GtkTextView   *text_view,
   if (hadj)
     g_return_if_fail (GTK_IS_ADJUSTMENT (hadj));
   else
-    hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
+    hadj = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
   if (vadj)
     g_return_if_fail (GTK_IS_ADJUSTMENT (vadj));
   else
-    vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
+    vadj = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
 
   if (priv->hadjustment && (priv->hadjustment != hadj))
     {
@@ -8098,8 +8080,9 @@ popup_position_func (GtkMenu   *menu,
                                    &cursor_rect);
 
   gtk_text_view_get_visible_rect (text_view, &onscreen_rect);
-  
-  gtk_widget_size_request (text_view->priv->popup_menu, &req);
+
+  gtk_widget_get_preferred_size (text_view->priv->popup_menu,
+                                 &req, NULL);
 
   gtk_widget_get_allocation (widget, &allocation);
 
@@ -8400,18 +8383,15 @@ text_window_realize (GtkTextWindow *win,
   attributes.height = win->allocation.height;
   attributes.wclass = GDK_INPUT_OUTPUT;
   attributes.visual = gtk_widget_get_visual (win->widget);
-  attributes.colormap = gtk_widget_get_colormap (win->widget);
   attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK;
 
-  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
 
   window = gtk_widget_get_window (widget);
 
   win->window = gdk_window_new (window,
                                 &attributes, attributes_mask);
 
-  gdk_window_set_back_pixmap (win->window, NULL, FALSE);
-  
   gdk_window_show (win->window);
   gdk_window_set_user_data (win->window, win->widget);
   gdk_window_lower (win->window);
@@ -8441,7 +8421,7 @@ text_window_realize (GtkTextWindow *win,
       if (gtk_widget_is_sensitive (widget))
         {
           /* I-beam cursor */
-          cursor = gdk_cursor_new_for_display (gdk_drawable_get_display (window),
+          cursor = gdk_cursor_new_for_display (gdk_window_get_display (window),
                                               GDK_XTERM);
           gdk_window_set_cursor (win->bin_window, cursor);
           gdk_cursor_unref (cursor);