[vte/wip/html: 424/425] Merge remote-tracking branch 'nomeata/master-html-copy-paste' into work-master



commit a71e0eb84d1b88f764d13b5bb38e3faaded672d2
Merge: 7f76548 0beed99
Author: Christian Persch <chpe gnome org>
Date:   Fri Apr 11 11:38:53 2014 +0200

    Merge remote-tracking branch 'nomeata/master-html-copy-paste' into work-master
    
    Works, but needs much cleanup before it can be merged.
    
    Conflicts:
        src/vte-private.h
        src/vte.c

 src/vte-private.h |   24 +++-
 src/vte.c         |  356 ++++++++++++++++++++++++++++++++++++++++++-----------
 src/vte.h         |    3 +
 3 files changed, 306 insertions(+), 77 deletions(-)
---
diff --cc src/vte-private.h
index 72bd232,06e9ee6..1ccc44b
--- a/src/vte-private.h
+++ b/src/vte-private.h
@@@ -282,8 -274,13 +291,13 @@@ struct _VteTerminalPrivate 
        } selection_origin, selection_last;
        VteVisualPosition selection_start, selection_end;
  
+       /* Clipboard data information. */
+       char *selection_text[LAST_VTE_SELECTION];
+       char *selection_html[LAST_VTE_SELECTION];
+       GtkClipboard *clipboard[LAST_VTE_SELECTION];
+ 
        /* Miscellaneous options. */
 -      VteTerminalEraseBinding backspace_binding, delete_binding;
 +      VteEraseBinding backspace_binding, delete_binding;
        gboolean meta_sends_escape;
        gboolean audible_bell;
        gboolean visible_bell;
diff --cc src/vte.c
index a1dc1bf,54291aa..cb15f93
--- a/src/vte.c
+++ b/src/vte.c
@@@ -132,7 -138,6 +132,12 @@@ static void _vte_check_cursor_blink(Vte
  
  static gboolean process_timeout (gpointer data);
  static gboolean update_timeout (gpointer data);
 +static cairo_region_t *vte_cairo_get_clip_region (cairo_t *cr);
++static void vte_terminal_determine_colors_internal(VteTerminal *terminal,
++                                                   const VteCellAttr *attr,
++                                                   gboolean selected,
++                                                   gboolean cursor,
++                                                   guint *pfore, guint *pback);
  
  enum {
      COPY_CLIPBOARD,
@@@ -5881,39 -6205,44 +5896,61 @@@ static voi
  vte_terminal_copy_cb(GtkClipboard *clipboard, GtkSelectionData *data,
                     guint info, gpointer owner)
  {
+       VteSelection sel;
        VteTerminal *terminal;
        terminal = owner;
-       if (terminal->pvt->selection != NULL) {
-               _VTE_DEBUG_IF(VTE_DEBUG_SELECTION) {
-                       int i;
-                       g_printerr("Setting selection (%"G_GSIZE_FORMAT" UTF-8 bytes.)\n",
-                               strlen(terminal->pvt->selection));
-                       for (i = 0; terminal->pvt->selection[i] != '\0'; i++) {
-                               g_printerr("0x%04x\n",
-                                       terminal->pvt->selection[i]);
+       for (sel = 0; sel < LAST_VTE_SELECTION; sel ++) {
+               if (clipboard == terminal->pvt->clipboard[sel] && terminal->pvt->selection_text[sel] != NULL) 
{
+                       _VTE_DEBUG_IF(VTE_DEBUG_SELECTION) {
+                               int i;
+                               g_printerr("Setting selection %d (%"G_GSIZE_FORMAT" UTF-8 bytes.)\n",
+                                       sel,
+                                       strlen(terminal->pvt->selection_text[sel]));
+                               for (i = 0; terminal->pvt->selection_text[sel][i] != '\0'; i++) {
+                                       g_printerr("0x%04x\n",
+                                               terminal->pvt->selection_text[sel][i]);
+                               }
+                       }
+                       if (info == VTE_TARGET_TEXT) {
+                               gtk_selection_data_set_text(data, terminal->pvt->selection_text[sel], -1);
+                       } else {
+                               gsize len;
+                               gchar *selection;
+ 
+                               g_assert(info == VTE_TARGET_HTML);
+ 
+                               /* Mozilla asks that we start our text/html with the Unicode byte order mark 
*/
+                               /* (Comment found in gtkimhtml.c of pidgin fame) */
+                               selection = g_convert(terminal->pvt->selection_html[sel],
+                                       -1, "UTF-16", "UTF-8", NULL, &len, NULL);
+                               gtk_selection_data_set(data,
+                                       gdk_atom_intern("text/html", FALSE),
+                                       16,
+                                       (const guchar *)selection,
+                                       len);
+                               g_free(selection);
                        }
                }
-               gtk_selection_data_set_text(data, terminal->pvt->selection, -1);
-       }
+       } 
  }
  
 +/* Convert the internal color code (either index or RGB, see vte-private.h) into RGB. */
 +static void
 +vte_terminal_get_rgb_from_index(const VteTerminal *terminal, guint index, PangoColor *color)
 +{
 +      if (index >= VTE_LEGACY_COLORS_OFFSET && index < VTE_LEGACY_COLORS_OFFSET + 
VTE_LEGACY_FULL_COLOR_SET_SIZE)
 +              index -= VTE_LEGACY_COLORS_OFFSET;
 +      if (index < VTE_PALETTE_SIZE) {
 +              memcpy(color, _vte_terminal_get_color(terminal, index), sizeof(PangoColor));
 +      } else if (index & VTE_RGB_COLOR) {
 +              color->red = ((index >> 16) & 0xFF) * 257;
 +              color->green = ((index >> 8) & 0xFF) * 257;
 +              color->blue = (index & 0xFF) * 257;
 +      } else {
 +              g_assert_not_reached();
 +      }
 +}
 +
  /**
   * VteSelectionFunc:
   * @terminal: terminal in which the cell is.
@@@ -6190,6 -6523,270 +6227,164 @@@ vte_terminal_get_text_include_trailing_
                                                   TRUE);
  }
  
 -static inline void
 -swap (guint *a, guint *b)
 -{
 -      guint tmp;
 -      tmp = *a, *a = *b, *b = tmp;
 -}
 -
 -static void
 -vte_terminal_determine_colors_internal(VteTerminal *terminal,
 -                                     const VteCellAttr *attr,
 -                                     gboolean selected,
 -                                     gboolean cursor,
 -                                     guint *pfore, guint *pback)
 -{
 -      guint fore, back;
 -
 -      g_assert(attr);
 -
 -      /* Start with cell colors */
 -      fore = attr->fore;
 -      back = attr->back;
 -
 -      /* Reverse-mode switches default fore and back colors */
 -      if (G_UNLIKELY (terminal->pvt->screen->reverse_mode)) {
 -              if (fore == VTE_DEF_FG)
 -                      fore = VTE_DEF_BG;
 -              if (back == VTE_DEF_BG)
 -                      back = VTE_DEF_FG;
 -      }
 -
 -      /* Handle bold by using set bold color or brightening */
 -      if (attr->bold) {
 -              if (fore == VTE_DEF_FG)
 -                      fore = VTE_BOLD_FG;
 -              else if (fore < VTE_LEGACY_COLOR_SET_SIZE) {
 -                      fore += VTE_COLOR_BRIGHT_OFFSET;
 -              }
 -      }
 -
 -      /* Handle half similarly */
 -      if (attr->half) {
 -              if (fore == VTE_DEF_FG)
 -                      fore = VTE_DIM_FG;
 -              else if ((fore < VTE_LEGACY_COLOR_SET_SIZE))
 -                      fore = corresponding_dim_index[fore];
 -      }
 -
 -      /* And standout */
 -      if (attr->standout) {
 -              if (back < VTE_LEGACY_COLOR_SET_SIZE)
 -                      back += VTE_COLOR_BRIGHT_OFFSET;
 -      }
 -
 -      /* Reverse cell? */
 -      if (attr->reverse) {
 -              swap (&fore, &back);
 -      }
 -
 -      /* Selection: use hightlight back, or inverse */
 -      if (selected) {
 -              /* XXX what if hightlight back is same color as current back? */
 -              if (terminal->pvt->highlight_color_set)
 -                      back = VTE_DEF_HL;
 -              else
 -                      swap (&fore, &back);
 -      }
 -
 -      /* Cursor: use cursor back, or inverse */
 -      if (cursor) {
 -              /* XXX what if cursor back is same color as current back? */
 -              if (terminal->pvt->cursor_color_set)
 -                      back = VTE_CUR_BG;
 -              else
 -                      swap (&fore, &back);
 -      }
 -
 -      /* Invisible? */
 -      if (attr->invisible) {
 -              fore = back;
 -      }
 -
 -      *pfore = fore;
 -      *pback = back;
 -}
 -
 -static inline void
 -vte_terminal_determine_colors (VteTerminal *terminal,
 -                             const VteCell *cell,
 -                             gboolean highlight,
 -                             guint *fore, guint *back)
 -{
 -      return vte_terminal_determine_colors_internal (terminal,
 -                                                     cell ? &cell->attr : &basic_cell.cell.attr,
 -                                                     highlight, FALSE,
 -                                                     fore, back);
 -}
 -
 -static inline void
 -vte_terminal_determine_cursor_colors (VteTerminal *terminal,
 -                                    const VteCell *cell,
 -                                    gboolean highlight,
 -                                    guint *fore, guint *back)
 -{
 -      return vte_terminal_determine_colors_internal (terminal,
 -                                                     cell ? &cell->attr : &basic_cell.cell.attr,
 -                                                     highlight, TRUE,
 -                                                     fore, back);
 -}
 -
 -
+ /*
+  * Compares the visual attributes of a VteCellAttr for equality, but ignores
+  * attributes that tend to change from character to character or are otherwise
+  * strange (in particular: fragment, columns).
+  */
+ static gboolean
+ vte_terminal_cellattr_equal(const VteCellAttr *attr1, const VteCellAttr *attr2) {
+       return (attr1->bold          == attr2->bold      &&
+               attr1->fore          == attr2->fore      &&
+               attr1->back          == attr2->back      &&
+               attr1->standout      == attr2->standout  &&
+               attr1->underline     == attr2->underline &&
+               attr1->strikethrough == attr2->strikethrough &&
+               attr1->reverse       == attr2->reverse   &&
+               attr1->blink         == attr2->blink     &&
+               attr1->half          == attr2->half      &&
+               attr1->invisible     == attr2->invisible);
+ }
+ 
+ /*
+  * Wraps a given string according to the VteCellAttr in HTML tags. Used
+  * old-style HTML (and not CSS) for better compatibility with, for example,
+  * evolution's mail editor component.
+  */
+ static gchar *
+ vte_terminal_cellattr_to_html(VteTerminal *terminal, const VteCellAttr *attr, const gchar *text) {
+       GString *string;
+       guint fore, back;
+ 
+       g_assert (terminal->pvt->palette_initialized);
+ 
+       string = g_string_new(text);
+ 
+       vte_terminal_determine_colors_internal (terminal, attr,
+                                               FALSE, FALSE,
+                                               &fore, &back);
+ 
+       if (attr->bold || attr->standout) {
+               g_string_prepend(string, "<b>");
+               g_string_append(string, "</b>");
+       }
 -      if (attr->fore != VTE_DEF_FG || attr->reverse) {
 -              PangoColor *color = &terminal->pvt->palette[fore];
 -              gchar *tag = g_strdup_printf(
 -                      "<font color=\"#%02X%02X%02X\">",
 -                      color->red >> 8,
 -                      color->green >> 8,
 -                      color->blue >> 8);
++      if (attr->fore != VTE_DEFAULT_FG || attr->reverse) {
++              PangoColor color;
++                char *tag;
++
++                vte_terminal_get_rgb_from_index(terminal, attr->fore, &color);
++              tag = g_strdup_printf("<font color=\"#%02X%02X%02X\">",
++                                      color.red >> 8,
++                                      color.green >> 8,
++                                      color.blue >> 8);
+               g_string_prepend(string, tag);
+               g_free(tag);
+               g_string_append(string, "</font>");
+       }
 -      if (attr->back != VTE_DEF_BG || attr->reverse) {
 -              PangoColor *color = &terminal->pvt->palette[back];
 -              gchar *tag = g_strdup_printf(
 -                      "<span style=\"background-color:#%02X%02X%02X\">",
 -                      color->red >> 8,
 -                      color->green >> 8,
 -                      color->blue >> 8);
++      if (attr->back != VTE_DEFAULT_BG || attr->reverse) {
++              PangoColor color;
++                char *tag;
++
++                vte_terminal_get_rgb_from_index(terminal, attr->back, &color);
++              tag = g_strdup_printf("<span style=\"background-color:#%02X%02X%02X\">",
++                                      color.red >> 8,
++                                      color.green >> 8,
++                                      color.blue >> 8);
+               g_string_prepend(string, tag);
+               g_free(tag);
+               g_string_append(string, "</span>");
+       }
+       if (attr->underline) {
+               g_string_prepend(string, "<u>");
+               g_string_append(string, "</u>");
+       }
+       if (attr->strikethrough) {
+               g_string_prepend(string, "<strike>");
+               g_string_append(string, "</strike>");
+       }
+       if (attr->blink) {
+               g_string_prepend(string, "<blink>");
+               g_string_append(string, "</blink>");
+       }
+       // reverse and invisible are not supported
+ 
+       return g_string_free(string, FALSE);
+ }
+ 
+ /*
+  * Similar to vte_terminal_find_charcell, but takes a VteCharAttribute for
+  * indexing and returns the VteCellAttr.
+  */
+ static const VteCellAttr *
+ vte_terminal_char_to_cell_attr(VteTerminal *terminal, VteCharAttributes *attr)
+ {
+       const VteCell *cell;
+ 
+       cell = vte_terminal_find_charcell(terminal, attr->column, attr->row);
+       if (cell)
+               return &cell->attr;
+       return NULL;
+ }
+ 
+ 
+ /**
+  * vte_terminal_attributes_to_html:
+  * @terminal: a #VteTerminal
+  * @text: A string as returned by the vte_terminal_get_* family of functions.
+  * @attrs: (array) (element-type Vte.CharAttributes): text attributes, as created by vte_terminal_get_*
+  *
+  * Marks the given text up according to the given attributes, using HTML <span>
+  * commands, and wraps the string in a <pre> element. The attributes have to be
+  * "fresh" in the sense that the terminal must not have changed since they were
+  * obtained using the vte_terminal_get* function.
+  *
+  * Returns: (transfer full): a newly allocated text string, or %NULL.
+  */
+ char *
+ vte_terminal_attributes_to_html(VteTerminal *terminal, const gchar *text, GArray *attrs) {
+       GString *string;
+       guint from,to;
+       const VteCellAttr *attr;
+       char *escaped, *marked;
+ 
+       g_assert(strlen(text) == attrs->len);
+ 
+       // Initial size fits perfectly if the text has no attributes and no
+       // characters that need to be escaped
+       string = g_string_sized_new (strlen(text) + 11);
+       
+       g_string_append(string, "<pre>");
+       // Find streches with equal attributes. Newlines are treated specially,
+       // so that the <span> do not cover multiple lines.
+       from = to = 0;
+       while (text[from] != '\0') {
+               g_assert(from == to);
+               if (text[from] == '\n') {
+                       g_string_append_c(string, '\n');
+                       from = ++to;
+               } else {
+                       attr = vte_terminal_char_to_cell_attr(terminal,
+                               &g_array_index(attrs, VteCharAttributes, from));
+                       while (text[to] != '\0' && text[to] != '\n' &&
+                              vte_terminal_cellattr_equal(attr,
+                                       vte_terminal_char_to_cell_attr(terminal,
+                                               &g_array_index(attrs, VteCharAttributes, to))))
+                       {
+                               to++;
+                       }
+                       escaped = g_markup_escape_text(text + from, to - from);
+                       marked = vte_terminal_cellattr_to_html(terminal, attr, escaped);
+                       g_string_append(string, marked);
+                       g_free(escaped);
+                       g_free(marked);
+                       from = to;
+               }
+       }
+       g_string_append(string, "</pre>");
+ 
+       return g_string_free(string, FALSE);
+ }
+ 
  /**
   * vte_terminal_get_cursor_position:
   * @terminal: a #VteTerminal
@@@ -6238,14 -6831,21 +6429,21 @@@ vte_terminal_copy(VteTerminal *terminal
                                            terminal->pvt->selection_start.row,
                                            0,
                                            terminal->pvt->selection_end.row,
 -                                          terminal->column_count,
 +                                          terminal->pvt->column_count,
                                            vte_cell_is_selected,
                                            NULL,
-                                           NULL);
-       terminal->pvt->has_selection = TRUE;
+                                           attributes);
+       terminal->pvt->selection_html[sel] =
+               vte_terminal_attributes_to_html(terminal,
+                                               terminal->pvt->selection_text[sel],
+                                               attributes);
+       g_array_free (attributes, TRUE);
+ 
+       if (sel == VTE_SELECTION_PRIMARY)                                           
+               terminal->pvt->has_selection = TRUE;
  
        /* Place the text on the clipboard. */
-       if (terminal->pvt->selection != NULL) {
+       if (terminal->pvt->selection_text[sel] != NULL) {
                _vte_debug_print(VTE_DEBUG_SELECTION,
                                "Assuming ownership of selection.\n");
                if (!targets) {
@@@ -8125,7 -8635,7 +8327,8 @@@ static voi
  vte_terminal_init(VteTerminal *terminal)
  {
        VteTerminalPrivate *pvt;
 +      GtkStyleContext *context;
+       GdkDisplay *display;
  
        _vte_debug_print(VTE_DEBUG_LIFECYCLE, "vte_terminal_init()\n");
  
@@@ -8213,6 -8725,12 +8416,11 @@@
          pvt->scrollback_lines = -1; /* force update in vte_terminal_set_scrollback_lines */
        vte_terminal_set_scrollback_lines(terminal, VTE_SCROLLBACK_INIT);
  
+       /* Selection info. */
 -      vte_terminal_set_word_chars(terminal, NULL);
+       display = gtk_widget_get_display(&terminal->widget);
+       pvt->clipboard[VTE_SELECTION_PRIMARY] = gtk_clipboard_get_for_display(display, GDK_SELECTION_PRIMARY);
+       pvt->clipboard[VTE_SELECTION_CLIPBOARD] = gtk_clipboard_get_for_display(display, 
GDK_SELECTION_CLIPBOARD);
+ 
        /* Miscellaneous options. */
        vte_terminal_set_backspace_binding(terminal, VTE_ERASE_AUTO);
        vte_terminal_set_delete_binding(terminal, VTE_ERASE_AUTO);
@@@ -8562,9 -9153,10 +8770,10 @@@ vte_terminal_finalize(GObject *object
  {
        GtkWidget *widget = GTK_WIDGET (object);
        VteTerminal *terminal = VTE_TERMINAL (object);
 -      GtkWidget *toplevel;
 +        VteTerminalPrivate *pvt = terminal->pvt;
        GtkClipboard *clipboard;
          GtkSettings *settings;
+       VteSelection sel;
        struct vte_match_regex *regex;
        guint i;
  
@@@ -8624,16 -9225,21 +8833,18 @@@
        /* Free any selected text, but if we currently own the selection,
         * throw the text onto the clipboard without an owner so that it
         * doesn't just disappear. */
-       if (terminal->pvt->selection != NULL) {
-               clipboard = vte_terminal_clipboard_get(terminal,
-                                                      GDK_SELECTION_PRIMARY);
-               if (gtk_clipboard_get_owner(clipboard) == object) {
-                       gtk_clipboard_set_text(clipboard,
-                                              terminal->pvt->selection,
-                                              -1);
+       for (sel = VTE_SELECTION_PRIMARY; sel < LAST_VTE_SELECTION; sel++) {
+               if (terminal->pvt->selection_text[sel] != NULL) {
+                       clipboard = terminal->pvt->clipboard[sel];
+                       if (gtk_clipboard_get_owner(clipboard) == object) {
+                               gtk_clipboard_set_text(clipboard,
+                                                      terminal->pvt->selection_text[sel],
+                                                      -1);
+                       }
+                       g_free(terminal->pvt->selection_text[sel]);
+                       g_free(terminal->pvt->selection_html[sel]);
                }
-               g_free(terminal->pvt->selection);
        }
 -      if (terminal->pvt->word_chars != NULL) {
 -              g_array_free(terminal->pvt->word_chars, TRUE);
 -      }
  
        /* Clear the output histories. */
        _vte_ring_fini(terminal->pvt->normal_screen.row_data);
@@@ -8828,128 -9470,52 +9039,127 @@@ vte_terminal_realize(GtkWidget *widget
        vte_terminal_background_update(terminal);
  }
  
 -/* Check if a unicode character is actually a graphic character we draw
 - * ourselves to handle cases where fonts don't have glyphs for them. */
 -static gboolean
 -vte_unichar_is_local_graphic(vteunistr c)
 +static inline void
 +swap (guint *a, guint *b)
  {
 -      if ((c >= 0x2500) && (c <= 0x257f)) {
 -              return TRUE;
 +      guint tmp;
 +      tmp = *a, *a = *b, *b = tmp;
 +}
 +
 +static void
 +vte_terminal_determine_colors_internal(VteTerminal *terminal,
-                                      const VteCell *cell,
++                                     const VteCellAttr *attr,
 +                                     gboolean selected,
 +                                     gboolean cursor,
 +                                     guint *pfore, guint *pback)
 +{
 +      guint fore, back;
 +
-       if (!cell)
-               cell = &basic_cell.cell;
++        g_assert(attr);
 +
 +      /* Start with cell colors */
-       fore = cell->attr.fore;
-       back = cell->attr.back;
++      fore = attr->fore;
++      back = attr->back;
 +
 +      /* Reverse-mode switches default fore and back colors */
 +      if (G_UNLIKELY (terminal->pvt->screen->reverse_mode)) {
 +              if (fore == VTE_DEFAULT_FG)
 +                      fore = VTE_DEFAULT_BG;
 +              if (back == VTE_DEFAULT_BG)
 +                      back = VTE_DEFAULT_FG;
        }
 -      switch (c) {
 -      case 0x00a3: /* british pound */
 -      case 0x00b0: /* degree */
 -      case 0x00b1: /* plus/minus */
 -      case 0x00b7: /* bullet */
 -      case 0x03c0: /* pi */
 -      case 0x2190: /* left arrow */
 -      case 0x2191: /* up arrow */
 -      case 0x2192: /* right arrow */
 -      case 0x2193: /* down arrow */
 -      case 0x2260: /* != */
 -      case 0x2264: /* <= */
 -      case 0x2265: /* >= */
 -      case 0x23ba: /* scanline 1/9 */
 -      case 0x23bb: /* scanline 3/9 */
 -      case 0x23bc: /* scanline 7/9 */
 -      case 0x23bd: /* scanline 9/9 */
 -      case 0x2409: /* HT symbol */
 -      case 0x240a: /* LF symbol */
 -      case 0x240b: /* VT symbol */
 -      case 0x240c: /* FF symbol */
 -      case 0x240d: /* CR symbol */
 -      case 0x2424: /* NL symbol */
 -      case 0x2592: /* checkerboard */
 -      case 0x25ae: /* solid rectangle */
 -      case 0x25c6: /* diamond */
 -              return TRUE;
 -              break;
 -      default:
 -              break;
 +
 +      /* Handle bold by using set bold color or brightening */
-       if (cell->attr.bold) {
++      if (attr->bold) {
 +              if (fore == VTE_DEFAULT_FG)
 +                      fore = VTE_BOLD_FG;
 +              else if (fore >= VTE_LEGACY_COLORS_OFFSET && fore < VTE_LEGACY_COLORS_OFFSET + 
VTE_LEGACY_COLOR_SET_SIZE) {
 +                      fore += VTE_COLOR_BRIGHT_OFFSET;
 +              }
        }
 -      return FALSE;
 +
 +      /* Handle half similarly */
-       if (cell->attr.half) {
++      if (attr->half) {
 +              if (fore == VTE_DEFAULT_FG)
 +                      fore = VTE_DIM_FG;
 +              else if (fore >= VTE_LEGACY_COLORS_OFFSET && fore < VTE_LEGACY_COLORS_OFFSET + 
VTE_LEGACY_COLOR_SET_SIZE)
 +                      fore = corresponding_dim_index[fore - VTE_LEGACY_COLORS_OFFSET];
 +      }
 +
 +      /* And standout */
-       if (cell->attr.standout) {
++      if (attr->standout) {
 +              if (back >= VTE_LEGACY_COLORS_OFFSET && back < VTE_LEGACY_COLORS_OFFSET + 
VTE_LEGACY_COLOR_SET_SIZE)
 +                      back += VTE_COLOR_BRIGHT_OFFSET;
 +      }
 +
 +      /* Reverse cell? */
-       if (cell->attr.reverse) {
++      if (attr->reverse) {
 +              swap (&fore, &back);
 +      }
 +
 +      /* Selection: use hightlight back/fore, or inverse */
 +      if (selected) {
 +              /* XXX what if hightlight back is same color as current back? */
 +              gboolean do_swap = TRUE;
 +              if (_vte_terminal_get_color(terminal, VTE_HIGHLIGHT_BG) != NULL) {
 +                      back = VTE_HIGHLIGHT_BG;
 +                      do_swap = FALSE;
 +              }
 +              if (_vte_terminal_get_color(terminal, VTE_HIGHLIGHT_FG) != NULL) {
 +                      fore = VTE_HIGHLIGHT_FG;
 +                      do_swap = FALSE;
 +              }
 +              if (do_swap)
 +                      swap (&fore, &back);
 +      }
 +
 +      /* Cursor: use cursor back, or inverse */
 +      if (cursor) {
 +              /* XXX what if cursor back is same color as current back? */
 +              if (_vte_terminal_get_color(terminal, VTE_CURSOR_BG) != NULL)
 +                      back = VTE_CURSOR_BG;
 +              else
 +                      swap (&fore, &back);
 +      }
 +
 +      /* Invisible? */
-       if (cell && cell->attr.invisible) {
++      if (attr->invisible) {
 +              fore = back;
 +      }
 +
 +      *pfore = fore;
 +      *pback = back;
  }
 +
 +static inline void
 +vte_terminal_determine_colors (VteTerminal *terminal,
 +                             const VteCell *cell,
 +                             gboolean highlight,
 +                             guint *fore, guint *back)
 +{
-       vte_terminal_determine_colors_internal (terminal, cell,
++      vte_terminal_determine_colors_internal (terminal, cell ? &cell->attr : &basic_cell.cell.attr,
 +                                                     highlight, FALSE,
 +                                                     fore, back);
 +}
 +
 +static inline void
 +vte_terminal_determine_cursor_colors (VteTerminal *terminal,
 +                                    const VteCell *cell,
 +                                    gboolean highlight,
 +                                    guint *fore, guint *back)
 +{
-       vte_terminal_determine_colors_internal (terminal, cell,
++      vte_terminal_determine_colors_internal (terminal, cell ? &cell->attr : &basic_cell.cell.attr,
 +                                                     highlight, TRUE,
 +                                                     fore, back);
 +}
 +
 +/* Check if a unicode character is actually a graphic character we draw
 + * ourselves to handle cases where fonts don't have glyphs for them. */
  static gboolean
 -vte_terminal_unichar_is_local_graphic(VteTerminal *terminal, vteunistr c, gboolean bold)
 +vte_unichar_is_local_graphic(vteunistr c)
  {
 -      return vte_unichar_is_local_graphic (c) &&
 -              !_vte_draw_has_char (terminal->pvt->draw, c, bold);
 +        /* Box Drawing & Block Elements */
 +        return (c >= 0x2500) && (c <= 0x259f);
  }
  
  static void
@@@ -12079,61 -13272,6 +12289,57 @@@ vte_terminal_set_scroll_on_keystroke(Vt
  }
  
  /**
 + * vte_terminal_set_rewrap_on_resize:
 + * @terminal: a #VteTerminal
 + * @rewrap: %TRUE if the terminal should rewrap on resize
 + *
 + * Controls whether or not the terminal will rewrap its contents, including
 + * the scrollback history, whenever the terminal's width changes.
 + *
 + * Since: 0.36
 + */
 +void
 +vte_terminal_set_rewrap_on_resize(VteTerminal *terminal, gboolean rewrap)
 +{
 +        VteTerminalPrivate *pvt;
 +
 +        g_return_if_fail(VTE_IS_TERMINAL(terminal));
 +
 +        pvt = terminal->pvt;
 +
 +        if (rewrap == pvt->rewrap_on_resize)
 +                return;
 +
 +        pvt->rewrap_on_resize = rewrap;
 +        g_object_notify (G_OBJECT (terminal), "rewrap-on-resize");
 +}
 +
 +/**
 + * vte_terminal_get_rewrap_on_resize:
 + * @terminal: a #VteTerminal
 + *
 + * Checks whether or not the terminal will rewrap its contents upon resize.
 + *
 + * Returns: %TRUE if rewrapping is enabled, %FALSE if not
 + *
 + * Since: 0.36
 + */
 +gboolean
 +vte_terminal_get_rewrap_on_resize(VteTerminal *terminal)
 +{
 +      g_return_val_if_fail(VTE_IS_TERMINAL(terminal), FALSE);
 +      return terminal->pvt->rewrap_on_resize;
 +}
 +
++/* Place the selected text onto the CLIPBOARD clipboard. Do this
++ * asynchronously, so that we can support the html target as well */
 +static void
 +vte_terminal_real_copy_clipboard(VteTerminal *terminal)
 +{
-       _vte_debug_print(VTE_DEBUG_SELECTION, "Copying to CLIPBOARD.\n");
-       if (terminal->pvt->selection != NULL) {
-               GtkClipboard *clipboard;
-               clipboard = vte_terminal_clipboard_get(terminal,
-                                                      GDK_SELECTION_CLIPBOARD);
-               gtk_clipboard_set_text(clipboard, terminal->pvt->selection, -1);
-       }
++      vte_terminal_copy(terminal, VTE_SELECTION_CLIPBOARD);
 +}
 +
 +/**
   * vte_terminal_copy_clipboard:
   * @terminal: a #VteTerminal
   *
@@@ -12575,7 -14161,7 +12781,8 @@@ vte_terminal_reset(VteTerminal *termina
                     gboolean clear_history)
  {
          VteTerminalPrivate *pvt;
 +        int i;
+       VteSelection sel;
  
        g_return_if_fail(VTE_IS_TERMINAL(terminal));
  
@@@ -12699,18 -14280,22 +12906,23 @@@
        pvt->selecting = FALSE;
        pvt->selecting_restart = FALSE;
        pvt->selecting_had_delta = FALSE;
-       if (pvt->selection != NULL) {
-               g_free(pvt->selection);
-               pvt->selection = NULL;
-               memset(&pvt->selection_origin, 0,
-                      sizeof(pvt->selection_origin));
-               memset(&pvt->selection_last, 0,
-                      sizeof(pvt->selection_last));
-               memset(&pvt->selection_start, 0,
-                      sizeof(pvt->selection_start));
-               memset(&pvt->selection_end, 0,
-                      sizeof(pvt->selection_end));
-       }
+       for (sel = VTE_SELECTION_PRIMARY; sel < LAST_VTE_SELECTION; sel++) {
+               if (pvt->selection_text[sel] != NULL) {
+                       g_free(pvt->selection_text[sel]);
+                       g_free(pvt->selection_html[sel]);
+                       pvt->selection_text[sel] = NULL;
+                       pvt->selection_html[sel] = NULL;
+               }
+       }
 -      memset(&pvt->selection_origin, 0,
 -             sizeof(&pvt->selection_origin));
 -      memset(&pvt->selection_last, 0,
 -             sizeof(&pvt->selection_last));
 -      memset(&pvt->selection_start, 0,
 -             sizeof(&pvt->selection_start));
 -      memset(&pvt->selection_end, 0,
 -             sizeof(&pvt->selection_end));
++        memset(&pvt->selection_origin, 0,
++               sizeof(pvt->selection_origin));
++        memset(&pvt->selection_last, 0,
++               sizeof(pvt->selection_last));
++        memset(&pvt->selection_start, 0,
++               sizeof(pvt->selection_start));
++        memset(&pvt->selection_end, 0,
++               sizeof(pvt->selection_end));
++
        /* Reset mouse motion events. */
        pvt->mouse_tracking_mode = MOUSE_TRACKING_NONE;
        pvt->mouse_last_button = 0;
diff --cc src/vte.h
index e1c60db,98714c5..abd7be9
--- a/src/vte.h
+++ b/src/vte.h
@@@ -318,8 -433,13 +318,11 @@@ char *vte_terminal_get_text_range(VteTe
                                  VteSelectionFunc is_selected,
                                  gpointer user_data,
                                  GArray *attributes);
+ char *vte_terminal_attributes_to_html(VteTerminal *terminal,
+                                     const gchar *text,
+                                     GArray *attributes);
  void vte_terminal_get_cursor_position(VteTerminal *terminal,
                                      glong *column, glong *row);
 -/* Display string matching:  clear all matching expressions. */
 -void vte_terminal_match_clear_all(VteTerminal *terminal);
  
  /* Add a matching expression, returning the tag the widget assigns to that
   * expression. */


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