Beispiel #1
0
void
_gtk_rbtree_remove (GtkRBTree *tree)
{
#ifdef G_ENABLE_DEBUG  
  GtkRBTree *tmp_tree;

  if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
    _gtk_rbtree_test (G_STRLOC, tree);
#endif
  
  /* ugly hack to make _fixup_validation work in the first iteration of the
   * loop below */
  GTK_RBNODE_UNSET_FLAG (tree->root, GTK_RBNODE_DESCENDANTS_INVALID);
  
  gtk_rbnode_adjust (tree->parent_tree, 
                     tree->parent_node,
                     0,
                     - (int) tree->root->total_count,
                     - tree->root->offset);

#ifdef G_ENABLE_DEBUG  
  tmp_tree = tree->parent_tree;
#endif

  _gtk_rbtree_free (tree);

#ifdef G_ENABLE_DEBUG  
  if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
    _gtk_rbtree_test (G_STRLOC, tmp_tree);
#endif
}
Beispiel #2
0
void
_gtk_pixel_cache_repaint (GtkPixelCache *cache,
			  GtkPixelCacheDrawFunc draw,
			  cairo_rectangle_int_t *view_rect,
			  cairo_rectangle_int_t *canvas_rect,
			  gpointer user_data)
{
  cairo_t *backing_cr;

  if (cache->surface &&
      cache->surface_dirty &&
      !cairo_region_is_empty (cache->surface_dirty))
    {
      backing_cr = cairo_create (cache->surface);
      gdk_cairo_region (backing_cr, cache->surface_dirty);
      cairo_clip (backing_cr);
      cairo_translate (backing_cr,
		       -cache->surface_x - canvas_rect->x - view_rect->x,
		       -cache->surface_y - canvas_rect->y - view_rect->y);
      cairo_set_source_rgba (backing_cr,
			     0.0, 0, 0, 0.0);
      cairo_set_operator (backing_cr, CAIRO_OPERATOR_SOURCE);
      cairo_paint (backing_cr);

      cairo_set_operator (backing_cr, CAIRO_OPERATOR_OVER);

      cairo_save (backing_cr);
      draw (backing_cr, user_data);
      cairo_restore (backing_cr);

#ifdef G_ENABLE_DEBUG
      if (gtk_get_debug_flags () & GTK_DEBUG_PIXEL_CACHE)
	{
	  GdkRGBA colors[] = {
	    { 1, 0, 0, 0.08},
	    { 0, 1, 0, 0.08},
	    { 0, 0, 1, 0.08},
	    { 1, 0, 1, 0.08},
	    { 1, 1, 0, 0.08},
	    { 0, 1, 1, 0.08},
	  };
	  static int current_color = 0;

	  gdk_cairo_set_source_rgba (backing_cr, &colors[(current_color++) % G_N_ELEMENTS (colors)]);
	  cairo_paint (backing_cr);
	}
#endif

      cairo_destroy (backing_cr);
    }

  if (cache->surface_dirty)
    {
      cairo_region_destroy (cache->surface_dirty);
      cache->surface_dirty = NULL;
    }
}
Beispiel #3
0
static void
_gtk_rbnode_free (GtkRBNode *node)
{
#ifdef G_ENABLE_DEBUG
  if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
    {
      node->left = (gpointer) 0xdeadbeef;
      node->right = (gpointer) 0xdeadbeef;
      node->parent = (gpointer) 0xdeadbeef;
      node->total_count = 56789;
      node->offset = 56789;
      node->count = 56789;
      node->flags = 0;
    }
#endif
  g_slice_free (GtkRBNode, node);
}
Beispiel #4
0
void
_gtk_rbtree_node_set_height (GtkRBTree *tree,
			     GtkRBNode *node,
			     gint       height)
{
  gint diff = height - GTK_RBNODE_GET_HEIGHT (node);

  if (diff == 0)
    return;

  gtk_rbnode_adjust (tree, node, 0, 0, diff);

#ifdef G_ENABLE_DEBUG  
  if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
    _gtk_rbtree_test (G_STRLOC, tree);
#endif
}
Beispiel #5
0
void
gtk_css_node_validate_internal (GtkCssNode *cssnode,
                                gint64      timestamp)
{
    GtkCssNode *child;

    /* If you run your application with
     *   GTK_DEBUG=no-css-cache
     * every invalidation will purge the cache and completely query
     * everything anew form the cache. This is slow (in particular
     * when animating), but useful for figuring out bugs.
     *
     * We achieve that by pretending that everything that could have
     * changed has and so we of course totally need to redo everything.
     *
     * Note that this also completely revalidates child widgets all
     * the time.
     */
    if (G_UNLIKELY (gtk_get_debug_flags () & GTK_DEBUG_NO_CSS_CACHE))
        cssnode->pending_changes |= GTK_CSS_CHANGE_ANY;

    if (!cssnode->invalid)
        return;

    gtk_css_node_ensure_style (cssnode, timestamp);

    /* need to set to FALSE then to TRUE here to make it chain up */
    gtk_css_node_set_invalid (cssnode, FALSE);
    if (!gtk_css_style_is_static (cssnode->style))
        gtk_css_node_set_invalid (cssnode, TRUE);

    GTK_CSS_NODE_GET_CLASS (cssnode)->validate (cssnode);

    for (child = gtk_css_node_get_first_child (cssnode);
            child;
            child = gtk_css_node_get_next_sibling (child))
    {
        if (child->visible)
            gtk_css_node_validate_internal (child, timestamp);
    }
}
Beispiel #6
0
GtkIconCache *
_gtk_icon_cache_new_for_path (const gchar *path)
{
    GtkIconCache *cache = NULL;
    GMappedFile *map;

    gchar *cache_filename;
    gint fd = -1;
    GStatBuf st;
    GStatBuf path_st;

    /* Check if we have a cache file */
    cache_filename = g_build_filename (path, "icon-theme.cache", NULL);

    GTK_NOTE (ICONTHEME,
              g_print ("look for cache in %s\n", path));

    if (g_stat (path, &path_st) < 0)
        goto done;

    /* Open the file and map it into memory */
    fd = g_open (cache_filename, O_RDONLY|_O_BINARY, 0);

    if (fd < 0)
        goto done;

#ifdef G_OS_WIN32

    /* Bug 660730: _fstat32 is only defined in msvcrt80.dll+/VS 2005+ */
    /*             or possibly in the msvcrt.dll linked to by the Windows DDK */
    /*             (will need to check on the Windows DDK part later) */
#if (_MSC_VER >= 1400 || __MSVCRT_VERSION__ >= 0x0800)
#undef fstat /* Just in case */
#define fstat _fstat32
#endif
#endif

    if (fstat (fd, &st) < 0 || st.st_size < 4)
        goto done;

    /* Verify cache is uptodate */
    if (st.st_mtime < path_st.st_mtime)
    {
        GTK_NOTE (ICONTHEME,
                  g_print ("cache outdated\n"));
        goto done;
    }

    map = g_mapped_file_new (cache_filename, FALSE, NULL);

    if (!map)
        goto done;

#ifdef G_ENABLE_DEBUG
    if (gtk_get_debug_flags () & GTK_DEBUG_ICONTHEME)
    {
        CacheInfo info;

        info.cache = g_mapped_file_get_contents (map);
        info.cache_size = g_mapped_file_get_length (map);
        info.n_directories = 0;
        info.flags = CHECK_OFFSETS|CHECK_STRINGS;

        if (!_gtk_icon_cache_validate (&info))
        {
            g_mapped_file_unref (map);
            g_warning ("Icon cache '%s' is invalid\n", cache_filename);

            goto done;
        }
    }
#endif

    GTK_NOTE (ICONTHEME, g_print ("found cache for %s\n", path));

    cache = g_new0 (GtkIconCache, 1);
    cache->ref_count = 1;
    cache->map = map;
    cache->buffer = g_mapped_file_get_contents (map);

done:
    g_free (cache_filename);
    if (fd >= 0)
        close (fd);

    return cache;
}
Beispiel #7
0
GtkRBNode *
_gtk_rbtree_insert_before (GtkRBTree *tree,
			   GtkRBNode *current,
			   gint       height,
			   gboolean   valid)
{
  GtkRBNode *node;
  gboolean left = TRUE;

#ifdef G_ENABLE_DEBUG  
  if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
    {
      g_print ("\n\n_gtk_rbtree_insert_before: %p\n", current);
      _gtk_rbtree_debug_spew (tree);
      _gtk_rbtree_test (G_STRLOC, tree);
    }
#endif /* G_ENABLE_DEBUG */
  
  if (current != NULL && !_gtk_rbtree_is_nil (current->left))
    {
      current = current->left;
      while (!_gtk_rbtree_is_nil (current->right))
	current = current->right;
      left = FALSE;
    }

  /* setup new node */
  node = _gtk_rbnode_new (tree, height);

  /* insert node in tree */
  if (current)
    {
      node->parent = current;
      if (left)
	current->left = node;
      else
	current->right = node;
      gtk_rbnode_adjust (tree, node->parent,
                         1, 1, height);
    }
  else
    {
      g_assert (_gtk_rbtree_is_nil (tree->root));
      tree->root = node;
      gtk_rbnode_adjust (tree->parent_tree, tree->parent_node,
                         0, 1, height);
    }

  if (valid)
    _gtk_rbtree_node_mark_valid (tree, node);
  else
    _gtk_rbtree_node_mark_invalid (tree, node);

  _gtk_rbtree_insert_fixup (tree, node);

#ifdef G_ENABLE_DEBUG  
  if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
    {
      g_print ("_gtk_rbtree_insert_before finished...\n");
      _gtk_rbtree_debug_spew (tree);
      g_print ("\n\n");
      _gtk_rbtree_test (G_STRLOC, tree);
    }
#endif /* G_ENABLE_DEBUG */
  
  return node;
}
Beispiel #8
0
void
_gtk_rbtree_remove_node (GtkRBTree *tree,
			 GtkRBNode *node)
{
  GtkRBNode *x, *y;
  gint y_height;
  guint y_total_count;
  
  g_return_if_fail (tree != NULL);
  g_return_if_fail (node != NULL);

  
#ifdef G_ENABLE_DEBUG
  if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
    {
      g_print ("\n\n_gtk_rbtree_remove_node: %p\n", node);
      _gtk_rbtree_debug_spew (tree);
      _gtk_rbtree_test (G_STRLOC, tree);
    }
#endif /* G_ENABLE_DEBUG */
  
  /* make sure we're deleting a node that's actually in the tree */
  for (x = node; !_gtk_rbtree_is_nil (x->parent); x = x->parent)
    ;
  g_return_if_fail (x == tree->root);

#ifdef G_ENABLE_DEBUG  
  if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
    _gtk_rbtree_test (G_STRLOC, tree);
#endif
  
  if (_gtk_rbtree_is_nil (node->left) ||
      _gtk_rbtree_is_nil (node->right))
    {
      y = node;
    }
  else
    {
      y = node->right;

      while (!_gtk_rbtree_is_nil (y->left))
	y = y->left;
    }

  y_height = GTK_RBNODE_GET_HEIGHT (y) 
             + (y->children ? y->children->root->offset : 0);
  y_total_count = 1 + (y->children ? y->children->root->total_count : 0);

  /* x is y's only child, or nil */
  if (!_gtk_rbtree_is_nil (y->left))
    x = y->left;
  else
    x = y->right;

  /* remove y from the parent chain */
  if (!_gtk_rbtree_is_nil (x))
    x->parent = y->parent;
  if (!_gtk_rbtree_is_nil (y->parent))
    {
      if (y == y->parent->left)
	y->parent->left = x;
      else
	y->parent->right = x;
    }
  else
    {
      tree->root = x;
    }

  /* We need to clean up the validity of the tree.
   */
  gtk_rbnode_adjust (tree, y, -1, - y_total_count, - y_height);

  if (GTK_RBNODE_GET_COLOR (y) == GTK_RBNODE_BLACK)
    _gtk_rbtree_remove_node_fixup (tree, x, y->parent);

  if (y != node)
    {
      gint node_height, node_total_count;

      /* We want to see how much we remove from the aggregate values.
       * This is all the children we remove plus the node's values.
       */
      node_height = GTK_RBNODE_GET_HEIGHT (node)
                    + (node->children ? node->children->root->offset : 0);
      node_total_count = 1
                         + (node->children ? node->children->root->total_count : 0);

      /* Move the node over */
      if (GTK_RBNODE_GET_COLOR (node) != GTK_RBNODE_GET_COLOR (y))
	y->flags ^= (GTK_RBNODE_BLACK | GTK_RBNODE_RED);

      y->left = node->left;
      if (!_gtk_rbtree_is_nil (y->left))
        y->left->parent = y;
      y->right = node->right;
      if (!_gtk_rbtree_is_nil (y->right))
        y->right->parent = y;
      y->parent = node->parent;
      if (!_gtk_rbtree_is_nil (y->parent))
        {
          if (y->parent->left == node)
            y->parent->left = y;
          else
            y->parent->right = y;
        }
      else
        {
          tree->root = y;
        }
      y->count = node->count;
      y->total_count = node->total_count;
      y->offset = node->offset;

      gtk_rbnode_adjust (tree, y, 
                         0,
                         y_total_count - node_total_count,
                         y_height - node_height);
    }

  _gtk_rbnode_free (node);

#ifdef G_ENABLE_DEBUG  
  if (gtk_get_debug_flags () & GTK_DEBUG_TREE)
    {
      g_print ("_gtk_rbtree_remove_node finished...\n");
      _gtk_rbtree_debug_spew (tree);
      g_print ("\n\n");
      _gtk_rbtree_test (G_STRLOC, tree);
    }
#endif /* G_ENABLE_DEBUG */  
}
static void
start_element (GMarkupParseContext *context,
               const gchar         *element_name,
               const gchar        **names,
               const gchar        **values,
               gpointer             user_data,
               GError             **error)
{
  ParserData *data = (ParserData*)user_data;

#ifdef G_ENABLE_DEBUG
  if (gtk_get_debug_flags () & GTK_DEBUG_BUILDER)
    {
      GString *tags = g_string_new ("");
      int i;
      for (i = 0; names[i]; i++)
        g_string_append_printf (tags, "%s=\"%s\" ", names[i], values[i]);

      if (i)
        {
          g_string_insert_c (tags, 0, ' ');
          g_string_truncate (tags, tags->len - 1);
        }
      g_print ("<%s%s>\n", element_name, tags->str);
      g_string_free (tags, TRUE);
    }
#endif

  if (!data->last_element && strcmp (element_name, "interface") != 0)
    {
      g_set_error (error, GTK_BUILDER_ERROR, 
		   GTK_BUILDER_ERROR_UNHANDLED_TAG,
		   _("Invalid root element: '%s'"),
		   element_name);
      return;
    }
  data->last_element = element_name;

  if (data->subparser)
    if (!subparser_start (context, element_name, names, values,
			  data, error))
      return;

  if (strcmp (element_name, "requires") == 0)
    parse_requires (data, element_name, names, values, error);
  else if (strcmp (element_name, "object") == 0)
    parse_object (context, data, element_name, names, values, error);
  else if (strcmp (element_name, "template") == 0)
    parse_template (context, data, element_name, names, values, error);
  else if (data->requested_objects && !data->inside_requested_object)
    {
      /* If outside a requested object, simply ignore this tag */
      return;
    }
  else if (strcmp (element_name, "child") == 0)
    parse_child (data, element_name, names, values, error);
  else if (strcmp (element_name, "property") == 0)
    parse_property (data, element_name, names, values, error);
  else if (strcmp (element_name, "signal") == 0)
    parse_signal (data, element_name, names, values, error);
  else if (strcmp (element_name, "interface") == 0)
    parse_interface (data, element_name, names, values, error);
  else if (strcmp (element_name, "menu") == 0)
    _gtk_builder_menu_start (data, element_name, names, values, error);
  else if (strcmp (element_name, "placeholder") == 0)
    {
      /* placeholder has no special treatmeant, but it needs an
       * if clause to avoid an error below.
       */
    }
  else
    if (!parse_custom (context, element_name, names, values,
		       data, error))
      g_set_error (error, GTK_BUILDER_ERROR, 
		   GTK_BUILDER_ERROR_UNHANDLED_TAG,
		   _("Unhandled tag: '%s'"),
		   element_name);
}
Beispiel #10
0
static void
_gtk_pixel_cache_create_surface_if_needed (GtkPixelCache         *cache,
					   GdkWindow             *window,
					   cairo_rectangle_int_t *view_rect,
					   cairo_rectangle_int_t *canvas_rect)
{
  cairo_rectangle_int_t rect;
  int surface_w, surface_h;
  cairo_content_t content;
  cairo_pattern_t *bg;
  double red, green, blue, alpha;

#ifdef G_ENABLE_DEBUG
  if (gtk_get_debug_flags () & GTK_DEBUG_NO_PIXEL_CACHE)
    return;
#endif

  content = cache->content;
  if (!content)
    {
      content = CAIRO_CONTENT_COLOR_ALPHA;
      bg = gdk_window_get_background_pattern (window);
      if (bg != NULL &&
          cairo_pattern_get_type (bg) == CAIRO_PATTERN_TYPE_SOLID &&
          cairo_pattern_get_rgba (bg, &red, &green, &blue, &alpha) == CAIRO_STATUS_SUCCESS &&
          alpha == 1.0)
        content = CAIRO_CONTENT_COLOR;
    }

  surface_w = view_rect->width;
  if (canvas_rect->width > surface_w)
    surface_w = MIN (surface_w + cache->extra_width, canvas_rect->width);

  surface_h = view_rect->height;
  if (canvas_rect->height > surface_h)
    surface_h = MIN (surface_h + cache->extra_height, canvas_rect->height);

  /* If current surface can't fit view_rect or is too large, kill it */
  if (cache->surface != NULL &&
      (cairo_surface_get_content (cache->surface) != content ||
       cache->surface_w < MAX(view_rect->width, surface_w - ALLOW_SMALLER_SIZE) ||
       cache->surface_w > surface_w + ALLOW_LARGER_SIZE ||
       cache->surface_h < MAX(view_rect->height, surface_h - ALLOW_SMALLER_SIZE) ||
       cache->surface_h > surface_h + ALLOW_LARGER_SIZE ||
       cache->surface_scale != gdk_window_get_scale_factor (window)))
    {
      cairo_surface_destroy (cache->surface);
      cache->surface = NULL;
      if (cache->surface_dirty)
	cairo_region_destroy (cache->surface_dirty);
      cache->surface_dirty = NULL;
    }

  /* Don't allocate a surface if view >= canvas, as we won't
     be scrolling then anyway */
  if (cache->surface == NULL &&
      (view_rect->width < canvas_rect->width ||
       view_rect->height < canvas_rect->height))
    {
      cache->surface_x = -canvas_rect->x;
      cache->surface_y = -canvas_rect->y;
      cache->surface_w = surface_w;
      cache->surface_h = surface_h;
      cache->surface_scale = gdk_window_get_scale_factor (window);

      cache->surface =
	gdk_window_create_similar_surface (window, content,
					   surface_w, surface_h);
      rect.x = 0;
      rect.y = 0;
      rect.width = surface_w;
      rect.height = surface_h;
      cache->surface_dirty =
	cairo_region_create_rectangle (&rect);
    }
}