gboolean
terminal_encoding_is_valid (TerminalEncoding *encoding)
{
  /* All of the printing ASCII characters from space (32) to the tilde (126) */
  static const char ascii_sample[] =
      " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
  char *converted;
  gsize bytes_read = 0, bytes_written = 0;
  GError *error = NULL;

  if (encoding->validity_checked)
    return encoding->valid;

  /* Test that the encoding is a proper superset of ASCII (which naive
   * apps are going to use anyway) by attempting to validate the text
   * using the current encoding.  This also flushes out any encodings
   * which the underlying GIConv implementation can't support.
   */
  converted = g_convert (ascii_sample, sizeof (ascii_sample) - 1,
                         terminal_encoding_get_charset (encoding), "UTF-8",
                         &bytes_read, &bytes_written, &error);

  /* The encoding is only valid if ASCII passes through cleanly. */
  encoding->valid = (bytes_read == (sizeof (ascii_sample) - 1)) &&
                    (converted != NULL) &&
                    (strcmp (converted, ascii_sample) == 0);

#ifdef GNOME_ENABLE_DEBUG
  _TERMINAL_DEBUG_IF (TERMINAL_DEBUG_ENCODINGS)
  {
    if (!encoding->valid)
      {
        _terminal_debug_print (TERMINAL_DEBUG_ENCODINGS,
                               "Rejecting encoding %s as invalid:\n",
                               terminal_encoding_get_charset (encoding));
        _terminal_debug_print (TERMINAL_DEBUG_ENCODINGS,
                               " input  \"%s\"\n",
                               ascii_sample);
        _terminal_debug_print (TERMINAL_DEBUG_ENCODINGS,
                               " output \"%s\" bytes read %" G_GSIZE_FORMAT " written %" G_GSIZE_FORMAT "\n",
                               converted ? converted : "(null)", bytes_read, bytes_written);
        if (error)
          _terminal_debug_print (TERMINAL_DEBUG_ENCODINGS,
                                 " Error: %s\n",
                                 error->message);
      }
    else
        _terminal_debug_print (TERMINAL_DEBUG_ENCODINGS,
                               "Encoding %s is valid\n\n",
                               terminal_encoding_get_charset (encoding));
  }
#endif

  g_clear_error (&error);
  g_free (converted);

  encoding->validity_checked = TRUE;
  return encoding->valid;
}
static void
init_encodings_combo (GtkWidget *widget)
{
  GtkCellRenderer *renderer;
  GHashTableIter ht_iter;
  gpointer key, value;
  gs_unref_object GtkListStore *store;

  store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);

  g_hash_table_iter_init (&ht_iter, terminal_app_get_encodings (terminal_app_get ()));
  while (g_hash_table_iter_next (&ht_iter, &key, &value)) {
    TerminalEncoding *encoding = value;
    GtkTreeIter iter;
    gs_free char *name;

    name = g_markup_printf_escaped ("%s <span size=\"small\">%s</span>",
                                    terminal_encoding_get_charset (encoding),
                                    encoding->name);
    gtk_list_store_insert_with_values (store, &iter, -1,
                                       ENCODINGS_COLUMN_MARKUP, name,
                                       ENCODINGS_COLUMN_ID, terminal_encoding_get_charset (encoding),
                                       -1);
  }

  /* Now turn on sorting */
  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
                                        ENCODINGS_COLUMN_MARKUP,
                                        GTK_SORT_ASCENDING);

  gtk_combo_box_set_id_column (GTK_COMBO_BOX (widget), ENCODINGS_COLUMN_ID);
  gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (store));

  /* Cell renderer */
  renderer = gtk_cell_renderer_text_new ();
  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), renderer, TRUE);
  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget), renderer,
                                  "markup", ENCODINGS_COLUMN_MARKUP, NULL);
}
Exemplo n.º 3
0
static void
liststore_insert_encoding (gpointer key,
                           TerminalEncoding *encoding,
                           GtkListStore *store)
{
	GtkTreeIter iter;

	if (!terminal_encoding_is_valid (encoding))
		return;

	gtk_list_store_insert_with_values (store, &iter, -1,
	                                   COLUMN_CHARSET, terminal_encoding_get_charset (encoding),
	                                   COLUMN_NAME, encoding->name,
	                                   COLUMN_DATA, encoding,
	                                   -1);
}
Exemplo n.º 4
0
/**
 * terminal_app_ensure_encoding:
 * @app:
 * @charset: (allow-none): a charset, or %NULL
 *
 * Ensures there's a #TerminalEncoding for @charset available. If @charset
 * is %NULL, returns the #TerminalEncoding for the locale's charset. If
 * @charset is not a known charset, returns a #TerminalEncoding for a
 * custom charset.
 *
 * Returns: (transfer none): a #TerminalEncoding, or %NULL
 */
TerminalEncoding *
terminal_app_ensure_encoding (TerminalApp *app,
                              const char *charset)
{
  TerminalEncoding *encoding;

  encoding = g_hash_table_lookup (app->encodings, charset_validated (charset));
  if (encoding == NULL)
    {
      encoding = terminal_encoding_new (charset,
                                        _("User Defined"),
                                        TRUE,
                                        TRUE /* scary! */);
      g_hash_table_insert (app->encodings,
                          (gpointer) terminal_encoding_get_charset (encoding),
                          encoding);
    }

  return encoding;
}