[vte/vte-next] Add vte_terminal_[sg]et_background_pattern



commit 2b756975201ceae4ce55634e86dc4564a142783b
Author: Christian Persch <chpe gnome org>
Date:   Tue May 3 14:27:28 2011 +0200

    Add vte_terminal_[sg]et_background_pattern
    
    ... which replace vte_terminal_set_background_image[_file] and
    vte_terminal_set_background_tint_color.

 doc/reference/Makefile.am      |    1 -
 doc/reference/vte-sections.txt |    5 +-
 src/Makefile.am                |    2 -
 src/vte-private.h              |    8 +-
 src/vte.c                      |  258 +++++++-------------------------
 src/vte.h                      |    8 +-
 src/vteapp.c                   |   27 +++-
 src/vtebg.c                    |  323 ----------------------------------------
 src/vtebg.h                    |   68 ---------
 src/vtedraw.c                  |   47 +-----
 src/vtedraw.h                  |   10 +-
 11 files changed, 92 insertions(+), 665 deletions(-)
---
diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am
index c9d1904..8a0449a 100644
--- a/doc/reference/Makefile.am
+++ b/doc/reference/Makefile.am
@@ -79,7 +79,6 @@ IGNORE_HFILES = \
 	stamp-vtetypebuiltins.h \
 	table.h \
 	trie.h \
-	vtebg.h \
 	vteconv.h \
 	vtedraw.h \
 	vteint.h \
diff --git a/doc/reference/vte-sections.txt b/doc/reference/vte-sections.txt
index 10a27d8..6644d02 100644
--- a/doc/reference/vte-sections.txt
+++ b/doc/reference/vte-sections.txt
@@ -36,9 +36,8 @@ vte_terminal_set_color_cursor_rgba
 vte_terminal_set_color_highlight_rgba
 vte_terminal_set_colors_rgba
 vte_terminal_set_default_colors
-vte_terminal_set_background_image
-vte_terminal_set_background_image_file
-vte_terminal_set_background_tint_color_rgba
+vte_terminal_get_background_pattern
+vte_terminal_set_background_pattern
 vte_terminal_set_scroll_background
 vte_terminal_set_cursor_shape
 vte_terminal_get_cursor_shape
diff --git a/src/Makefile.am b/src/Makefile.am
index 837cd22..4dc0203 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -56,8 +56,6 @@ libvte VTE_LIBRARY_SUFFIX_U@_la_SOURCES = \
 	vte-private.h \
 	vteaccess.c \
 	vteaccess.h \
-	vtebg.c \
-	vtebg.h \
 	vteconv.c \
 	vteconv.h \
 	vtedraw.c \
diff --git a/src/vte-private.h b/src/vte-private.h
index b3c4081..d9c7b1c 100644
--- a/src/vte-private.h
+++ b/src/vte-private.h
@@ -362,11 +362,9 @@ struct _VteTerminalPrivate {
         gchar *icon_title;
 	gchar *icon_title_changed;
 
-	/* Background images/"transparency". */
-	gboolean bg_update_pending;
-	GdkPixbuf *bg_pixbuf;
-	char *bg_file;
-        GdkRGBA bg_tint_color;
+        /* Background pattern */
+        cairo_pattern_t *bg_pattern;
+        gboolean bg_update_pending;
 
 	/* Key modifiers. */
 	GdkModifierType modifiers;
diff --git a/src/vte.c b/src/vte.c
index 594c95f..cb03578 100644
--- a/src/vte.c
+++ b/src/vte.c
@@ -142,9 +142,7 @@ enum {
         PROP_VSCROLL_POLICY,
         PROP_ALLOW_BOLD,
         PROP_AUDIBLE_BELL,
-        PROP_BACKGROUND_IMAGE_FILE,
-        PROP_BACKGROUND_IMAGE_PIXBUF,
-        PROP_BACKGROUND_TINT_COLOR,
+        PROP_BACKGROUND_PATTERN,
         PROP_BACKSPACE_BINDING,
         PROP_CURSOR_BLINK_MODE,
         PROP_CURSOR_SHAPE,
@@ -7581,10 +7579,8 @@ vte_terminal_init(VteTerminal *terminal)
 	gtk_widget_ensure_style(&terminal->widget);
 
 	/* Set up background information. */
-        pvt->bg_tint_color.red = 1.;
-        pvt->bg_tint_color.green = 1.;
-        pvt->bg_tint_color.blue = 1.;
-        pvt->bg_tint_color.alpha = .6;
+        pvt->bg_pattern = cairo_pattern_create_rgba (1., 1., 1., .6);
+
 	pvt->selection_block_mode = FALSE;
 	pvt->has_fonts = FALSE;
 
@@ -7906,6 +7902,7 @@ vte_terminal_finalize(GObject *object)
 {
     	GtkWidget *widget = GTK_WIDGET (object);
     	VteTerminal *terminal = VTE_TERMINAL (object);
+        VteTerminalPrivate *pvt = terminal->pvt;
 	GtkClipboard *clipboard;
         GtkSettings *settings;
 	struct vte_match_regex *regex;
@@ -7922,7 +7919,9 @@ vte_terminal_finalize(GObject *object)
 	_vte_iso2022_state_free(terminal->pvt->iso2022);
 
 	/* Free background info. */
-	g_free(terminal->pvt->bg_file);
+        if (pvt->bg_pattern) {
+                cairo_pattern_destroy (pvt->bg_pattern);
+        }
 
 	/* Free the font description. */
 	if (terminal->pvt->fontdesc != NULL) {
@@ -10507,14 +10506,8 @@ vte_terminal_get_property (GObject *object,
                 case PROP_AUDIBLE_BELL:
                         g_value_set_boolean (value, vte_terminal_get_audible_bell (terminal));
                         break;
-                case PROP_BACKGROUND_IMAGE_FILE:
-                        g_value_set_string (value, pvt->bg_file);
-                        break;
-                case PROP_BACKGROUND_IMAGE_PIXBUF:
-                        g_value_set_object (value, pvt->bg_pixbuf);
-                        break;
-                case PROP_BACKGROUND_TINT_COLOR:
-                        g_value_set_boxed (value, &pvt->bg_tint_color);
+                case PROP_BACKGROUND_PATTERN:
+                        g_value_set_pointer (value, pvt->bg_pattern);
                         break;
                 case PROP_BACKSPACE_BINDING:
                         g_value_set_enum (value, pvt->backspace_binding);
@@ -10605,14 +10598,8 @@ vte_terminal_set_property (GObject *object,
                 case PROP_AUDIBLE_BELL:
                         vte_terminal_set_audible_bell (terminal, g_value_get_boolean (value));
                         break;
-                case PROP_BACKGROUND_IMAGE_FILE:
-                        vte_terminal_set_background_image_file (terminal, g_value_get_string (value));
-                        break;
-                case PROP_BACKGROUND_IMAGE_PIXBUF:
-                        vte_terminal_set_background_image (terminal, g_value_get_object (value));
-                        break;
-                case PROP_BACKGROUND_TINT_COLOR:
-                        vte_terminal_set_background_tint_color_rgba (terminal, g_value_get_boxed (value));
+                case PROP_BACKGROUND_PATTERN:
+                        vte_terminal_set_background_pattern (terminal, g_value_get_pointer (value));
                         break;
                 case PROP_BACKSPACE_BINDING:
                         vte_terminal_set_backspace_binding (terminal, g_value_get_enum (value));
@@ -11299,60 +11286,17 @@ vte_terminal_class_init(VteTerminalClass *klass)
                                        G_PARAM_READWRITE | STATIC_PARAMS));
      
         /**
-         * VteTerminal:background-image-file: (type filename):
-         *
-         * Sets a background image file for the widget.  If specified by
-         * #VteTerminal:background-tint-color:, the terminal will tint its
-         * in-memory copy of the image before applying it to the terminal.
-         * 
-         * Since: 0.20
-         */
-        g_object_class_install_property
-                (gobject_class,
-                 PROP_BACKGROUND_IMAGE_FILE,
-                 g_param_spec_string ("background-image-file", NULL, NULL,
-                                      NULL,
-                                      G_PARAM_READWRITE | STATIC_PARAMS));
-
-        /**
-         * VteTerminal:background-image-pixbuf:
-         *
-         * Sets a background image for the widget.  Text which would otherwise be
-         * drawn using the default background color will instead be drawn over the
-         * specified image.  If necessary, the image will be tiled to cover the
-         * widget's entire visible area. If specified by
-         * #VteTerminal:background-tint-color:, the terminal will tint its
-         * in-memory copy of the image before applying it to the terminal.
-         * 
-         * Since: 0.20
-         */
-        g_object_class_install_property
-                (gobject_class,
-                 PROP_BACKGROUND_IMAGE_PIXBUF,
-                 g_param_spec_object ("background-image-pixbuf", NULL, NULL,
-                                      GDK_TYPE_PIXBUF,
-                                      G_PARAM_READWRITE | STATIC_PARAMS));
-
-        /**
-         * VteTerminal:background-tint-color:
+         * VteTerminal:background-pattern: (type cairo_pattern_t):
          *
-         * If a background image has been set using #VteTerminal:background-image-file: or
-         * #VteTerminal:background-image-pixbuf:, and
-         * and the alpha value set by VteTerminal:background-tint-color: is greater than 0.0,
-         * the terminal
-         * will adjust the color of the image before drawing the image.  To do so,
-         * the terminal will create a copy of the background image
-         * and modify its pixel values.  The initial tint color
-         * is black.
+         * Sets a background pattern for the widget.
          * 
-         * Since: 0.20
+         * Since: 0.30
          */
         g_object_class_install_property
                 (gobject_class,
-                 PROP_BACKGROUND_TINT_COLOR,
-                 g_param_spec_boxed ("background-tint-color", NULL, NULL,
-                                     GDK_TYPE_RGBA,
-                                     G_PARAM_READWRITE | STATIC_PARAMS));
+                 PROP_BACKGROUND_PATTERN,
+                 g_param_spec_pointer ("background-pattern", NULL, NULL,
+                                       G_PARAM_READWRITE | STATIC_PARAMS));
 
         /**
          * VteTerminal:backspace-binding:
@@ -11977,7 +11921,6 @@ static gboolean
 vte_terminal_background_update(VteTerminal *terminal)
 {
 	const GdkRGBA *entry;
-        GdkRGBA rgba;
         GdkColor color;
 
 	/* If we're not realized yet, don't worry about it, because we get
@@ -12005,30 +11948,8 @@ vte_terminal_background_update(VteTerminal *terminal)
         color.blue = entry->blue * 65535.;
 	gtk_widget_modify_bg (&terminal->widget, GTK_STATE_NORMAL, &color);
 
-        rgba = *entry;
-        rgba.alpha *= terminal->pvt->bg_tint_color.alpha;
-        _vte_draw_set_background_solid (terminal->pvt->draw, &rgba);
-
-	if (terminal->pvt->bg_file) {
-		_vte_draw_set_background_image(terminal->pvt->draw,
-					       VTE_BG_SOURCE_FILE,
-					       NULL,
-					       terminal->pvt->bg_file,
-					       &terminal->pvt->bg_tint_color);
-	} else
-	if (GDK_IS_PIXBUF(terminal->pvt->bg_pixbuf)) {
-		_vte_draw_set_background_image(terminal->pvt->draw,
-					       VTE_BG_SOURCE_PIXBUF,
-					       terminal->pvt->bg_pixbuf,
-					       NULL,
-					       &terminal->pvt->bg_tint_color);
-	} else {
-		_vte_draw_set_background_image(terminal->pvt->draw,
-					       VTE_BG_SOURCE_NONE,
-					       NULL,
-					       NULL,
-					       &terminal->pvt->bg_tint_color);
-	}
+        _vte_draw_set_background_pattern(terminal->pvt->draw,
+                                         terminal->pvt->bg_pattern);
 
 	/* Note that the update has finished. */
 	terminal->pvt->bg_update_pending = FALSE;
@@ -12054,102 +11975,71 @@ vte_terminal_queue_background_update(VteTerminal *terminal)
 }
 
 /**
- * vte_terminal_set_background_tint_color_rgba:
+ * vte_terminal_get_background_pattern:
  * @terminal: a #VteTerminal
- * @rgba: (allow-none): a color which the terminal background should be tinted to if
- *
- * If a background image has been set using
- * vte_terminal_set_background_image(),
- * vte_terminal_set_background_image_file(),
- * and the value set by
- * alpha value in @rgba is greater than 0.0, the terminal
- * will adjust the color of the image before drawing the image.  To do so,
- * the terminal will create a copy of the background image
- * and modify its pixel values.  The initial tint color
- * is black.
+ *
+ * Returns the current background pattern for the widget.
+ *
+ * Returns: (transfer none): a #cairo_pattern_t, or %NULL
  *
  * Since: 0.30
  */
-void
-vte_terminal_set_background_tint_color_rgba(VteTerminal *terminal,
-                                            const GdkRGBA *rgba)
+cairo_pattern_t *
+vte_terminal_get_background_pattern(VteTerminal *terminal)
 {
-        VteTerminalPrivate *pvt;
-
-        g_return_if_fail(VTE_IS_TERMINAL(terminal));
-        g_return_if_fail(rgba != NULL);
-
-        pvt = terminal->pvt;
-
-        _vte_debug_print(VTE_DEBUG_MISC,
-                        "Setting background tint to rgba(%.3f,%.3f,%.3f,%.3f)\n",
-                        rgba->red, rgba->green, rgba->blue, rgba->alpha);
-        if (gdk_rgba_equal(&pvt->bg_tint_color, rgba))
-                return;
-
-        pvt->bg_tint_color = *rgba;
-
-        g_object_notify(G_OBJECT (terminal), "background-tint-color");
+        g_return_val_if_fail(VTE_IS_TERMINAL(terminal), NULL);
 
-        vte_terminal_queue_background_update(terminal);
+        return terminal->pvt->bg_pattern;
 }
 
 /**
- * vte_terminal_set_background_image:
+ * vte_terminal_set_background_pattern:
  * @terminal: a #VteTerminal
- * @image: (allow-none): a #GdkPixbuf to use, or %NULL to unset the background
+ * @pattern: (allow-none): a #cairo_pattern_t, or %NULL to unset the background
  *
- * Sets a background image for the widget.  Text which would otherwise be
+ * Sets a background pattern for the widget.  Text which would otherwise be
  * drawn using the default background color will instead be drawn over the
- * specified image.  If necessary, the image will be tiled to cover the
- * widget's entire visible area. If specified by
- * vte_terminal_set_background_tint_color_rgba(), the terminal will tint its
- * in-memory copy of the image before applying it to the terminal.
+ * specified pattern.  If necessary, the pattern will be tiled to cover the
+ * widget's entire visible area.
+ *
+ * If using a surface pattern, it is recommended to update the pattern
+ * on #GtkWidget:realize to use a similar surface to the widget's window.
+ *
+ * Since: 0.30
  */
 void
-vte_terminal_set_background_image(VteTerminal *terminal, GdkPixbuf *image)
+vte_terminal_set_background_pattern(VteTerminal *terminal,
+                                    cairo_pattern_t *pattern)
 {
         VteTerminalPrivate *pvt;
         GObject *object;
 
 	g_return_if_fail(VTE_IS_TERMINAL(terminal));
-	g_return_if_fail(image==NULL || GDK_IS_PIXBUF(image));
+        if (pattern) {
+                g_return_if_fail(cairo_pattern_get_extend(pattern) != CAIRO_EXTEND_NONE);
+        }
 
         object = G_OBJECT(terminal);
         pvt = terminal->pvt;
 
-        if (image && image == pvt->bg_pixbuf)
+        if (pattern == pvt->bg_pattern)
                 return;
 
 	_vte_debug_print(VTE_DEBUG_MISC,
-			"%s background image.\n",
-			GDK_IS_PIXBUF(image) ? "Setting" : "Clearing");
+			"%s background pattern.\n",
+			pattern ? "Setting" : "Clearing");
 
         g_object_freeze_notify(object);
 
-	/* Get a ref to the new image if there is one.  Do it here just in
-	 * case we're actually given the same one we're already using. */
-	if (image != NULL) {
-		g_object_ref(image);
-	}
-
-	/* Unref the previous background image. */
-	if (pvt->bg_pixbuf != NULL) {
-		g_object_unref(pvt->bg_pixbuf);
-	}
-
-	/* Clear a background file name, if one was set. */
-        if (pvt->bg_file) {
-                g_free(pvt->bg_file);
-                pvt->bg_file = NULL;
-
-                g_object_notify(object, "background-image-file");
+        if (pvt->bg_pattern) {
+                cairo_pattern_destroy (pvt->bg_pattern);
         }
+        if (pattern) {
+                cairo_pattern_reference (pattern);
+        }
+        pvt->bg_pattern = pattern;
 
-	/* Set the new background. */
-	pvt->bg_pixbuf = image;
-
-        g_object_notify(object, "background-image-pixbuf");
+        g_object_notify(object, "background-pattern");
 
 	vte_terminal_queue_background_update(terminal);
 
@@ -12157,50 +12047,6 @@ vte_terminal_set_background_image(VteTerminal *terminal, GdkPixbuf *image)
 }
 
 /**
- * vte_terminal_set_background_image_file:
- * @terminal: a #VteTerminal
- * @path: (type filename): path to an image file
- *
- * Sets a background image for the widget.  If specified by
- * vte_terminal_set_background_tint_color_rgba(), the terminal will tint its
- * in-memory copy of the image before applying it to the terminal.
- */
-void
-vte_terminal_set_background_image_file(VteTerminal *terminal, const char *path)
-{
-        VteTerminalPrivate *pvt;
-        GObject *object;
-
-	g_return_if_fail(VTE_IS_TERMINAL(terminal));
-
-        object = G_OBJECT(terminal);
-        pvt = terminal->pvt;
-
-	_vte_debug_print(VTE_DEBUG_MISC,
-			"Loading background image from `%s'.\n", path);
-
-        g_object_freeze_notify(G_OBJECT(terminal));
-
-	/* Save this background type. */
-	g_free(pvt->bg_file);
-	pvt->bg_file = g_strdup(path);
-
-	/* Turn off other background types. */
-	if (pvt->bg_pixbuf != NULL) {
-		g_object_unref(pvt->bg_pixbuf);
-		pvt->bg_pixbuf = NULL;
-
-                g_object_notify(object, "background-image-pixbuf");
-	}
-
-        g_object_notify(object, "background-image-file");
-
-	vte_terminal_queue_background_update(terminal);
-
-        g_object_thaw_notify(G_OBJECT(terminal));
-}
-
-/**
  * vte_terminal_get_has_selection:
  * @terminal: a #VteTerminal
  *
diff --git a/src/vte.h b/src/vte.h
index 52ca560..013437f 100644
--- a/src/vte.h
+++ b/src/vte.h
@@ -250,11 +250,9 @@ void vte_terminal_set_colors_rgba(VteTerminal *terminal,
 void vte_terminal_set_default_colors(VteTerminal *terminal);
 
 /* Background effects. */
-void vte_terminal_set_background_image(VteTerminal *terminal, GdkPixbuf *image);
-void vte_terminal_set_background_image_file(VteTerminal *terminal,
-					    const char *path);
-void vte_terminal_set_background_tint_color_rgba(VteTerminal *terminal,
-                                                 const GdkRGBA *rgba);
+cairo_pattern_t *vte_terminal_get_background_pattern(VteTerminal *terminal);
+void vte_terminal_set_background_pattern(VteTerminal *terminal,
+                                         cairo_pattern_t *pattern);
 
 /* Set whether or not the cursor blinks. */
 void vte_terminal_set_cursor_blink_mode(VteTerminal *terminal,
diff --git a/src/vteapp.c b/src/vteapp.c
index 8fdaf48..24a86ab 100644
--- a/src/vteapp.c
+++ b/src/vteapp.c
@@ -887,11 +887,30 @@ main(int argc, char **argv)
 	vte_terminal_set_scroll_on_keystroke(terminal, TRUE);
 	vte_terminal_set_scrollback_lines(terminal, lines);
 	vte_terminal_set_mouse_autohide(terminal, TRUE);
+
 	if (background != NULL) {
-		vte_terminal_set_background_image_file(terminal,
-						       background);
-	}
-	vte_terminal_set_background_tint_color_rgba(terminal, &tint);
+                cairo_surface_t *surface;
+
+                surface = cairo_image_surface_create_from_png (background);
+                if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS) {
+                        cairo_pattern_t *pattern;
+
+                        pattern = cairo_pattern_create_for_surface(surface);
+                        cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+                        vte_terminal_set_background_pattern(terminal, pattern);
+                        cairo_pattern_destroy(pattern);
+                } else {
+                        g_printerr("Failed to create background pattern\n");
+                }
+                cairo_surface_destroy (surface);
+        } else {
+                cairo_pattern_t *pattern;
+
+                pattern = cairo_pattern_create_rgba (tint.red, tint.green, tint.blue, tint.alpha);
+                vte_terminal_set_background_pattern(terminal, pattern);
+                cairo_pattern_destroy(pattern);
+        }
+
 	vte_terminal_set_colors_rgba(terminal, &fore, &back, NULL, 0);
 	if (highlight_set) {
 		vte_terminal_set_color_highlight_rgba(terminal, &highlight);
diff --git a/src/vtedraw.c b/src/vtedraw.c
index 23de77a..4d9bede 100644
--- a/src/vtedraw.c
+++ b/src/vtedraw.c
@@ -24,7 +24,6 @@
 #include <gtk/gtk.h>
 #include <glib.h>
 #include "debug.h"
-#include "vtebg.h"
 #include "vtedraw.h"
 #include "vte-private.h"
 
@@ -802,46 +801,14 @@ _vte_draw_end (struct _vte_draw *draw)
 }
 
 void
-_vte_draw_set_background_solid(struct _vte_draw *draw,
-                               const GdkRGBA *color)
+_vte_draw_set_background_pattern (struct _vte_draw *draw,
+                                  cairo_pattern_t *pattern)
 {
-	if (draw->bg_pattern)
-		cairo_pattern_destroy (draw->bg_pattern);
-
-	draw->bg_pattern = cairo_pattern_create_rgba (color->red,
-						      color->green,
-						      color->blue,
-						      color->alpha);
-}
-
-void
-_vte_draw_set_background_image (struct _vte_draw *draw,
-			        VteBgSourceType type,
-			        GdkPixbuf *pixbuf,
-			        const char *filename,
-			        const GdkRGBA *color)
-{
-	cairo_surface_t *surface;
-
-	/* Need a valid draw->cr for cairo_get_target () */
-	_vte_draw_start (draw);
-
-	surface = vte_bg_get_surface (vte_bg_get_for_screen (gtk_widget_get_screen (draw->widget)),
-				     type, pixbuf, filename,
-				     color,
-				     cairo_get_target(draw->cr));
-
-	_vte_draw_end (draw);
-
-	if (!surface)
-		return;
-
-	if (draw->bg_pattern)
-		cairo_pattern_destroy (draw->bg_pattern);
-
-	draw->bg_pattern = cairo_pattern_create_for_surface (surface);
-	cairo_surface_destroy (surface);
-	cairo_pattern_set_extend (draw->bg_pattern, CAIRO_EXTEND_REPEAT);
+        if (draw->bg_pattern)
+                cairo_pattern_destroy (draw->bg_pattern);
+        if (pattern)
+                cairo_pattern_reference (pattern);
+        draw->bg_pattern = pattern;
 }
 
 void
diff --git a/src/vtedraw.h b/src/vtedraw.h
index 6a1ae90..6c1863e 100644
--- a/src/vtedraw.h
+++ b/src/vtedraw.h
@@ -24,7 +24,6 @@
 
 #include <glib.h>
 #include <gtk/gtk.h>
-#include "vtebg.h"
 #include "vte.h"
 #include "vteunistr.h"
 
@@ -67,13 +66,8 @@ void _vte_draw_free(struct _vte_draw *draw);
 void _vte_draw_start(struct _vte_draw *draw);
 void _vte_draw_end(struct _vte_draw *draw);
 
-void _vte_draw_set_background_solid(struct _vte_draw *draw,
-                                    const GdkRGBA *color);
-void _vte_draw_set_background_image(struct _vte_draw *draw,
-				    VteBgSourceType type,
-				    GdkPixbuf *pixbuf,
-				    const char *file,
-				    const GdkRGBA *color);
+void _vte_draw_set_background_pattern (struct _vte_draw *draw,
+                                       cairo_pattern_t *pattern);
 void _vte_draw_set_background_scroll(struct _vte_draw *draw,
 				     gint x, gint y);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]