static gboolean gimp_plug_in_recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { GimpPlugIn *plug_in = data; gboolean got_message = FALSE; #ifdef G_OS_WIN32 /* Workaround for GLib bug #137968: sometimes we are called for no * reason... */ if (cond == 0) return TRUE; #endif if (plug_in->my_read == NULL) return TRUE; g_object_ref (plug_in); if (cond & (G_IO_IN | G_IO_PRI)) { GimpWireMessage msg; memset (&msg, 0, sizeof (GimpWireMessage)); if (! gimp_wire_read_msg (plug_in->my_read, &msg, plug_in)) { gimp_plug_in_close (plug_in, TRUE); } else { gimp_plug_in_handle_message (plug_in, &msg); gimp_wire_destroy (&msg); got_message = TRUE; } } if (cond & (G_IO_ERR | G_IO_HUP)) { if (cond & G_IO_HUP) plug_in->hup = TRUE; if (plug_in->open) gimp_plug_in_close (plug_in, TRUE); } if (! got_message) { GimpPlugInProcFrame *frame = gimp_plug_in_get_proc_frame (plug_in); GimpProgress *progress = frame ? frame->progress : NULL; gimp_message (plug_in->manager->gimp, G_OBJECT (progress), GIMP_MESSAGE_ERROR, _("Plug-in crashed: \"%s\"\n(%s)\n\n" "The dying plug-in may have messed up GIMP's internal " "state. You may want to save your images and restart " "GIMP to be on the safe side."), gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file)); } g_object_unref (plug_in); return TRUE; }
static GimpPDBStatusType lcms_icc_apply (GimpColorConfig *config, GimpRunMode run_mode, gint32 image, GFile *file, GimpColorRenderingIntent intent, gboolean bpc, gboolean *dont_ask) { GimpPDBStatusType status = GIMP_PDB_SUCCESS; cmsHPROFILE src_profile = NULL; cmsHPROFILE dest_profile = NULL; GError *error = NULL; g_return_val_if_fail (GIMP_IS_COLOR_CONFIG (config), GIMP_PDB_CALLING_ERROR); g_return_val_if_fail (image != -1, GIMP_PDB_CALLING_ERROR); if (file) g_object_ref (file); else if (config->rgb_profile) file = g_file_new_for_path (config->rgb_profile); if (file) { GError *error = NULL; dest_profile = gimp_lcms_profile_open_from_file (file, &error); if (! dest_profile) { g_message ("%s", error->message); g_clear_error (&error); return GIMP_PDB_EXECUTION_ERROR; } if (! gimp_lcms_profile_is_rgb (dest_profile)) { g_message (_("Color profile '%s' is not for RGB color space."), gimp_file_get_utf8_name (file)); cmsCloseProfile (dest_profile); g_object_unref (file); return GIMP_PDB_EXECUTION_ERROR; } } src_profile = lcms_image_get_profile (config, image, &error); if (error) { g_message ("%s", error->message); g_clear_error (&error); } if (! src_profile && ! dest_profile) return GIMP_PDB_SUCCESS; if (! src_profile) src_profile = gimp_lcms_create_srgb_profile (); if (! dest_profile) dest_profile = gimp_lcms_create_srgb_profile (); if (gimp_lcms_profile_is_equal (src_profile, dest_profile)) { gchar *src_label = gimp_lcms_profile_get_label (src_profile); gchar *dest_label = gimp_lcms_profile_get_label (dest_profile); cmsCloseProfile (src_profile); cmsCloseProfile (dest_profile); g_printerr ("lcms: skipping conversion because profiles seem to be equal:\n"); g_printerr (" %s\n", src_label); g_printerr (" %s\n", dest_label); g_free (src_label); g_free (dest_label); if (file) g_object_unref (file); return GIMP_PDB_SUCCESS; } if (run_mode == GIMP_RUN_INTERACTIVE && ! lcms_icc_apply_dialog (image, src_profile, dest_profile, dont_ask)) { status = GIMP_PDB_CANCEL; } if (status == GIMP_PDB_SUCCESS && ! lcms_image_apply_profile (image, src_profile, dest_profile, file, intent, bpc)) { status = GIMP_PDB_EXECUTION_ERROR; } cmsCloseProfile (src_profile); cmsCloseProfile (dest_profile); if (file) g_object_unref (file); return status; }
GSList * plug_in_rc_parse (Gimp *gimp, GFile *file, GError **error) { GScanner *scanner; GEnumClass *enum_class; GSList *plug_in_defs = NULL; gint protocol_version = GIMP_PROTOCOL_VERSION; gint file_version = PLUG_IN_RC_FILE_VERSION; GTokenType token; g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL); g_return_val_if_fail (G_IS_FILE (file), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); scanner = gimp_scanner_new_gfile (file, error); if (! scanner) return NULL; enum_class = g_type_class_ref (GIMP_TYPE_ICON_TYPE); g_scanner_scope_add_symbol (scanner, 0, "protocol-version", GINT_TO_POINTER (PROTOCOL_VERSION)); g_scanner_scope_add_symbol (scanner, 0, "file-version", GINT_TO_POINTER (FILE_VERSION)); g_scanner_scope_add_symbol (scanner, 0, "plug-in-def", GINT_TO_POINTER (PLUG_IN_DEF)); g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF, "proc-def", GINT_TO_POINTER (PROC_DEF)); g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF, "locale-def", GINT_TO_POINTER (LOCALE_DEF)); g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF, "help-def", GINT_TO_POINTER (HELP_DEF)); g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF, "has-init", GINT_TO_POINTER (HAS_INIT)); g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF, "proc-arg", GINT_TO_POINTER (PROC_ARG)); g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF, "menu-path", GINT_TO_POINTER (MENU_PATH)); g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF, "icon", GINT_TO_POINTER (ICON)); g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF, "load-proc", GINT_TO_POINTER (LOAD_PROC)); g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF, "save-proc", GINT_TO_POINTER (SAVE_PROC)); g_scanner_scope_add_symbol (scanner, LOAD_PROC, "extension", GINT_TO_POINTER (EXTENSION)); g_scanner_scope_add_symbol (scanner, LOAD_PROC, "prefix", GINT_TO_POINTER (PREFIX)); g_scanner_scope_add_symbol (scanner, LOAD_PROC, "magic", GINT_TO_POINTER (MAGIC)); g_scanner_scope_add_symbol (scanner, LOAD_PROC, "mime-type", GINT_TO_POINTER (MIME_TYPE)); g_scanner_scope_add_symbol (scanner, LOAD_PROC, "handles-uri", GINT_TO_POINTER (HANDLES_URI)); g_scanner_scope_add_symbol (scanner, LOAD_PROC, "thumb-loader", GINT_TO_POINTER (THUMB_LOADER)); g_scanner_scope_add_symbol (scanner, SAVE_PROC, "extension", GINT_TO_POINTER (EXTENSION)); g_scanner_scope_add_symbol (scanner, SAVE_PROC, "prefix", GINT_TO_POINTER (PREFIX)); g_scanner_scope_add_symbol (scanner, SAVE_PROC, "mime-type", GINT_TO_POINTER (MIME_TYPE)); g_scanner_scope_add_symbol (scanner, SAVE_PROC, "handles-uri", GINT_TO_POINTER (HANDLES_URI)); token = G_TOKEN_LEFT_PAREN; while (protocol_version == GIMP_PROTOCOL_VERSION && file_version == PLUG_IN_RC_FILE_VERSION && g_scanner_peek_next_token (scanner) == token) { token = g_scanner_get_next_token (scanner); switch (token) { case G_TOKEN_LEFT_PAREN: token = G_TOKEN_SYMBOL; break; case G_TOKEN_SYMBOL: switch (GPOINTER_TO_INT (scanner->value.v_symbol)) { case PROTOCOL_VERSION: token = G_TOKEN_INT; if (gimp_scanner_parse_int (scanner, &protocol_version)) token = G_TOKEN_RIGHT_PAREN; break; case FILE_VERSION: token = G_TOKEN_INT; if (gimp_scanner_parse_int (scanner, &file_version)) token = G_TOKEN_RIGHT_PAREN; break; case PLUG_IN_DEF: g_scanner_set_scope (scanner, PLUG_IN_DEF); token = plug_in_def_deserialize (gimp, scanner, &plug_in_defs); g_scanner_set_scope (scanner, 0); break; default: break; } break; case G_TOKEN_RIGHT_PAREN: token = G_TOKEN_LEFT_PAREN; break; default: /* do nothing */ break; } } if (protocol_version != GIMP_PROTOCOL_VERSION || file_version != PLUG_IN_RC_FILE_VERSION || token != G_TOKEN_LEFT_PAREN) { if (protocol_version != GIMP_PROTOCOL_VERSION) { g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_VERSION, _("Skipping '%s': wrong GIMP protocol version."), gimp_file_get_utf8_name (file)); } else if (file_version != PLUG_IN_RC_FILE_VERSION) { g_set_error (error, GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_VERSION, _("Skipping '%s': wrong pluginrc file format version."), gimp_file_get_utf8_name (file)); } else { g_scanner_get_next_token (scanner); g_scanner_unexp_token (scanner, token, NULL, NULL, NULL, _("fatal parse error"), TRUE); } g_slist_free_full (plug_in_defs, (GDestroyNotify) g_object_unref); plug_in_defs = NULL; } g_type_class_unref (enum_class); gimp_scanner_destroy (scanner); return g_slist_reverse (plug_in_defs); }
static void file_open_location_response (GtkDialog *dialog, gint response_id, Gimp *gimp) { GtkWidget *entry; GtkWidget *box; const gchar *text = NULL; if (response_id != GTK_RESPONSE_OK) { box = g_object_get_data (G_OBJECT (dialog), "progress-box"); if (box && GIMP_PROGRESS_BOX (box)->active) gimp_progress_cancel (GIMP_PROGRESS (box)); else gtk_widget_destroy (GTK_WIDGET (dialog)); return; } entry = g_object_get_data (G_OBJECT (dialog), "location-entry"); gtk_editable_set_editable (GTK_EDITABLE (entry), FALSE); gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK, FALSE); text = gtk_entry_get_text (GTK_ENTRY (entry)); if (text && strlen (text)) { GimpImage *image; gchar *filename; GFile *file; GimpPDBStatusType status; GError *error = NULL; filename = g_filename_from_uri (text, NULL, NULL); if (filename) { file = g_file_new_for_uri (text); g_free (filename); } else { file = file_utils_filename_to_file (gimp, text, &error); } box = gimp_progress_box_new (); gtk_container_set_border_width (GTK_CONTAINER (box), 12); gtk_box_pack_end (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), box, FALSE, FALSE, 0); g_object_set_data (G_OBJECT (dialog), "progress-box", box); if (file) { GFile *entered_file = g_file_new_for_uri (text); gtk_widget_show (box); image = file_open_with_proc_and_display (gimp, gimp_get_user_context (gimp), GIMP_PROGRESS (box), file, entered_file, FALSE, NULL, G_OBJECT (gtk_widget_get_screen (entry)), gimp_widget_get_monitor (entry), &status, &error); g_object_unref (entered_file); if (image == NULL && status != GIMP_PDB_CANCEL) { gimp_message (gimp, G_OBJECT (box), GIMP_MESSAGE_ERROR, _("Opening '%s' failed:\n\n%s"), gimp_file_get_utf8_name (file), error->message); g_clear_error (&error); } g_object_unref (file); } else { gimp_message (gimp, G_OBJECT (box), GIMP_MESSAGE_ERROR, _("Opening '%s' failed:\n\n%s"), text, error->message); g_clear_error (&error); gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK, TRUE); gtk_editable_set_editable (GTK_EDITABLE (entry), TRUE); return; } } gtk_widget_destroy (GTK_WIDGET (dialog)); }
/** * gimp_scanner_new_gfile: * @file: a #GFile * @error: return location for #GError, or %NULL * * Return value: The new #GScanner. * * Since: 2.10 **/ GScanner * gimp_scanner_new_gfile (GFile *file, GError **error) { GScanner *scanner; gchar *path; g_return_val_if_fail (G_IS_FILE (file), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); path = g_file_get_path (file); if (path) { GMappedFile *mapped; mapped = g_mapped_file_new (path, FALSE, error); g_free (path); if (! mapped) { if (error) { (*error)->domain = GIMP_CONFIG_ERROR; (*error)->code = ((*error)->code == G_FILE_ERROR_NOENT ? GIMP_CONFIG_ERROR_OPEN_ENOENT : GIMP_CONFIG_ERROR_OPEN); } return NULL; } /* gimp_scanner_new() takes a "name" for the scanner, not a filename */ scanner = gimp_scanner_new (gimp_file_get_utf8_name (file), mapped, NULL, error); g_scanner_input_text (scanner, g_mapped_file_get_contents (mapped), g_mapped_file_get_length (mapped)); } else { GInputStream *input; input = G_INPUT_STREAM (g_file_read (file, NULL, error)); if (! input) { if (error) { (*error)->domain = GIMP_CONFIG_ERROR; (*error)->code = ((*error)->code == G_IO_ERROR_NOT_FOUND ? GIMP_CONFIG_ERROR_OPEN_ENOENT : GIMP_CONFIG_ERROR_OPEN); } return NULL; } g_object_set_data (G_OBJECT (input), "gimp-data", file); scanner = gimp_scanner_new_stream (input, error); g_object_unref (input); } return scanner; }
GList * gimp_palette_load (GimpContext *context, GFile *file, GInputStream *input, GError **error) { GimpPalette *palette = NULL; GimpPaletteEntry *entry; GDataInputStream *data_input; gchar *str; gsize str_len; gchar *tok; gint r, g, b; gint linenum; g_return_val_if_fail (G_IS_FILE (file), NULL); g_return_val_if_fail (G_IS_INPUT_STREAM (input), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); data_input = g_data_input_stream_new (input); r = g = b = 0; linenum = 1; str_len = 1024; str = gimp_data_input_stream_read_line_always (data_input, &str_len, NULL, error); if (! str) goto failed; if (! g_str_has_prefix (str, "GIMP Palette")) { g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ, _("Missing magic header.")); g_free (str); goto failed; } g_free (str); palette = g_object_new (GIMP_TYPE_PALETTE, "mime-type", "application/x-gimp-palette", NULL); linenum++; str_len = 1024; str = gimp_data_input_stream_read_line_always (data_input, &str_len, NULL, error); if (! str) goto failed; if (g_str_has_prefix (str, "Name: ")) { gchar *utf8; utf8 = gimp_any_to_utf8 (g_strstrip (str + strlen ("Name: ")), -1, _("Invalid UTF-8 string in palette file '%s'"), gimp_file_get_utf8_name (file)); gimp_object_take_name (GIMP_OBJECT (palette), utf8); g_free (str); linenum++; str_len = 1024; str = gimp_data_input_stream_read_line_always (data_input, &str_len, NULL, error); if (! str) goto failed; if (g_str_has_prefix (str, "Columns: ")) { gint columns; if (! gimp_ascii_strtoi (g_strstrip (str + strlen ("Columns: ")), NULL, 10, &columns)) { g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_READ, _("Invalid column count.")); g_free (str); goto failed; } if (columns < 0 || columns > 256) { g_message (_("Reading palette file '%s': " "Invalid number of columns in line %d. " "Using default value."), gimp_file_get_utf8_name (file), linenum); columns = 0; } gimp_palette_set_columns (palette, columns); g_free (str); linenum++; str_len = 1024; str = gimp_data_input_stream_read_line_always (data_input, &str_len, NULL, error); if (! str) goto failed; } } else /* old palette format */ { gimp_object_take_name (GIMP_OBJECT (palette), g_path_get_basename (gimp_file_get_utf8_name (file))); } while (str) { GError *my_error = NULL; if (str[0] != '#' && str[0] != '\0') { tok = strtok (str, " \t"); if (tok) r = atoi (tok); else g_message (_("Reading palette file '%s': " "Missing RED component in line %d."), gimp_file_get_utf8_name (file), linenum); tok = strtok (NULL, " \t"); if (tok) g = atoi (tok); else g_message (_("Reading palette file '%s': " "Missing GREEN component in line %d."), gimp_file_get_utf8_name (file), linenum); tok = strtok (NULL, " \t"); if (tok) b = atoi (tok); else g_message (_("Reading palette file '%s': " "Missing BLUE component in line %d."), gimp_file_get_utf8_name (file), linenum); /* optional name */ tok = strtok (NULL, "\n"); if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) g_message (_("Reading palette file '%s': " "RGB value out of range in line %d."), gimp_file_get_utf8_name (file), linenum); /* don't call gimp_palette_add_entry here, it's rather inefficient */ entry = g_slice_new0 (GimpPaletteEntry); gimp_rgba_set_uchar (&entry->color, (guchar) r, (guchar) g, (guchar) b, 255); entry->name = g_strdup (tok ? tok : _("Untitled")); entry->position = gimp_palette_get_n_colors (palette); palette->colors = g_list_prepend (palette->colors, entry); palette->n_colors++; } g_free (str); linenum++; str_len = 1024; str = g_data_input_stream_read_line (data_input, &str_len, NULL, &my_error); if (! str && my_error) { g_message (_("Reading palette file '%s': " "Read %d colors from truncated file: %s"), gimp_file_get_utf8_name (file), g_list_length (palette->colors), my_error->message); g_clear_error (&my_error); } } palette->colors = g_list_reverse (palette->colors); g_object_unref (data_input); return g_list_prepend (NULL, palette); failed: g_object_unref (data_input); if (palette) g_object_unref (palette); g_prefix_error (error, _("In line %d of palette file: "), linenum); return NULL; }
GList * gimp_palette_load_css (GimpContext *context, GFile *file, GInputStream *input, GError **error) { GimpPalette *palette; GDataInputStream *data_input; gchar *name; GRegex *regex; gchar *buf; g_return_val_if_fail (G_IS_FILE (file), NULL); g_return_val_if_fail (G_IS_INPUT_STREAM (input), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); regex = g_regex_new (".*color.*:(?P<param>.*);", G_REGEX_CASELESS, 0, error); if (! regex) return NULL; name = g_path_get_basename (gimp_file_get_utf8_name (file)); palette = GIMP_PALETTE (gimp_palette_new (context, name)); g_free (name); data_input = g_data_input_stream_new (input); do { gsize buf_len = 1024; buf = g_data_input_stream_read_line (data_input, &buf_len, NULL, NULL); if (buf) { GMatchInfo *matches; if (g_regex_match (regex, buf, 0, &matches)) { GimpRGB color; gchar *word = g_match_info_fetch_named (matches, "param"); if (gimp_rgb_parse_css (&color, word, -1)) { if (! gimp_palette_find_entry (palette, &color, NULL)) { gimp_palette_add_entry (palette, -1, NULL, &color); } } g_free (word); } g_match_info_free (matches); g_free (buf); } } while (buf); g_regex_unref (regex); g_object_unref (data_input); return g_list_prepend (NULL, palette); }
/** * gimp_config_writer_new_gfile: * @file: a #GFile * @atomic: if %TRUE the file is written atomically * @header: text to include as comment at the top of the file * @error: return location for errors * * Creates a new #GimpConfigWriter and sets it up to write to * @file. If @atomic is %TRUE, a temporary file is used to avoid * possible race conditions. The temporary file is then moved to @file * when the writer is closed. * * Return value: a new #GimpConfigWriter or %NULL in case of an error * * Since: 2.10 **/ GimpConfigWriter * gimp_config_writer_new_gfile (GFile *file, gboolean atomic, const gchar *header, GError **error) { GimpConfigWriter *writer; GOutputStream *output; GFile *dir; g_return_val_if_fail (G_IS_FILE (file), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); dir = g_file_get_parent (file); if (dir && ! g_file_query_exists (dir, NULL)) { if (! g_file_make_directory_with_parents (dir, NULL, error)) g_prefix_error (error, _("Could not create directory '%s' for '%s': "), gimp_file_get_utf8_name (dir), gimp_file_get_utf8_name (file)); } g_object_unref (dir); if (error && *error) return NULL; if (atomic) { output = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, error)); if (! output) g_prefix_error (error, _("Could not create temporary file for '%s': "), gimp_file_get_utf8_name (file)); } else { output = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, error)); } if (! output) return NULL; writer = g_slice_new0 (GimpConfigWriter); writer->output = output; writer->file = g_object_ref (file); writer->buffer = g_string_new (NULL); if (header) { gimp_config_writer_comment (writer, header); gimp_config_writer_linefeed (writer); } return writer; }
gboolean gimp_tags_user_install (void) { GFile *file; GOutputStream *output; GMarkupParser markup_parser; GimpXmlParser *xml_parser; const char *tags_locale; GimpTagsInstaller tags_installer = { 0, }; GError *error = NULL; gboolean result = TRUE; /* This is a special string to specify the language identifier to * look for in the gimp-tags-default.xml file. Please translate the * C in it according to the name of the po file used for * gimp-tags-default.xml. E.g. lithuanian for the translation, * that would be "tags-locale:lt". */ tags_locale = _("tags-locale:C"); if (g_str_has_prefix (tags_locale, "tags-locale:")) { tags_locale += strlen ("tags-locale:"); if (*tags_locale && *tags_locale != 'C') tags_installer.locale = tags_locale; } else { g_warning ("Wrong translation for 'tags-locale:', fix the translation!"); } tags_installer.buf = g_string_new (NULL); g_string_append (tags_installer.buf, "<?xml version='1.0' encoding='UTF-8'?>\n"); g_string_append (tags_installer.buf, "<tags>\n"); markup_parser.start_element = gimp_tags_installer_load_start_element; markup_parser.end_element = gimp_tags_installer_load_end_element; markup_parser.text = gimp_tags_installer_load_text; markup_parser.passthrough = NULL; markup_parser.error = NULL; xml_parser = gimp_xml_parser_new (&markup_parser, &tags_installer); file = gimp_data_directory_file ("tags", "gimp-tags-default.xml", NULL); result = gimp_xml_parser_parse_gfile (xml_parser, file, &error); g_object_unref (file); gimp_xml_parser_free (xml_parser); if (! result) { g_string_free (tags_installer.buf, TRUE); return FALSE; } g_string_append (tags_installer.buf, "\n</tags>\n"); file = gimp_directory_file (GIMP_TAGS_FILE, NULL); output = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error)); if (! output) { g_printerr ("%s\n", error->message); result = FALSE; } else if (! g_output_stream_write_all (output, tags_installer.buf->str, tags_installer.buf->len, NULL, NULL, &error)) { GCancellable *cancellable = g_cancellable_new (); g_printerr (_("Error writing '%s': %s"), gimp_file_get_utf8_name (file), error->message); result = FALSE; /* Cancel the overwrite initiated by g_file_replace(). */ g_cancellable_cancel (cancellable); g_output_stream_close (output, cancellable, NULL); g_object_unref (cancellable); } else if (! g_output_stream_close (output, NULL, &error)) { g_printerr (_("Error closing '%s': %s"), gimp_file_get_utf8_name (file), error->message); result = FALSE; } if (output) g_object_unref (output); g_clear_error (&error); g_object_unref (file); g_string_free (tags_installer.buf, TRUE); return result; }
/** * gimp_color_profile_open_from_file: * @file: a #GFile * @error: return location for #GError * * This function opens an ICC color profile from @file. * * Return value: the #GimpColorProfile, or %NULL. On error, %NULL is * returned and @error is set. * * Since: 2.10 **/ GimpColorProfile gimp_color_profile_open_from_file (GFile *file, GError **error) { GimpColorProfile profile = NULL; gchar *path; g_return_val_if_fail (G_IS_FILE (file), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); path = g_file_get_path (file); if (path) { GMappedFile *mapped; const guint8 *data; gsize length; mapped = g_mapped_file_new (path, FALSE, error); if (! mapped) return NULL; data = (const guint8 *) g_mapped_file_get_contents (mapped); length = g_mapped_file_get_length (mapped); profile = cmsOpenProfileFromMem (data, length); g_mapped_file_unref (mapped); } else { GFileInfo *info; info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, NULL, error); if (info) { GInputStream *input; goffset length = g_file_info_get_size (info); guint8 *data = g_malloc (length); g_object_unref (info); input = G_INPUT_STREAM (g_file_read (file, NULL, error)); if (input) { gsize bytes_read; if (g_input_stream_read_all (input, data, length, &bytes_read, NULL, error) && bytes_read == length) { profile = cmsOpenProfileFromMem (data, length); } g_object_unref (input); } g_free (data); } } if (! profile && error && *error == NULL) g_set_error (error, gimp_color_profile_error_quark (), 0, _("'%s' does not appear to be an ICC color profile"), gimp_file_get_utf8_name (file)); return profile; }
gboolean gimp_gradient_save_pov (GimpGradient *gradient, GFile *file, GError **error) { GOutputStream *output; GString *string; GimpGradientSegment *seg; gchar buf[G_ASCII_DTOSTR_BUF_SIZE]; gchar color_buf[4][G_ASCII_DTOSTR_BUF_SIZE]; GError *my_error = NULL; g_return_val_if_fail (GIMP_IS_GRADIENT (gradient), FALSE); g_return_val_if_fail (G_IS_FILE (file), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); output = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, error)); if (! output) return FALSE; string = g_string_new ("/* color_map file created by GIMP */\n" "/* https://www.gimp.org/ */\n" "color_map {\n"); for (seg = gradient->segments; seg; seg = seg->next) { /* Left */ g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->left); g_ascii_formatd (color_buf[0], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->left_color.r); g_ascii_formatd (color_buf[1], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->left_color.g); g_ascii_formatd (color_buf[2], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->left_color.b); g_ascii_formatd (color_buf[3], G_ASCII_DTOSTR_BUF_SIZE, "%f", 1.0 - seg->left_color.a); g_string_append_printf (string, "\t[%s color rgbt <%s, %s, %s, %s>]\n", buf, color_buf[0], color_buf[1], color_buf[2], color_buf[3]); /* Middle */ g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->middle); g_ascii_formatd (color_buf[0], G_ASCII_DTOSTR_BUF_SIZE, "%f", (seg->left_color.r + seg->right_color.r) / 2.0); g_ascii_formatd (color_buf[1], G_ASCII_DTOSTR_BUF_SIZE, "%f", (seg->left_color.g + seg->right_color.g) / 2.0); g_ascii_formatd (color_buf[2], G_ASCII_DTOSTR_BUF_SIZE, "%f", (seg->left_color.b + seg->right_color.b) / 2.0); g_ascii_formatd (color_buf[3], G_ASCII_DTOSTR_BUF_SIZE, "%f", 1.0 - (seg->left_color.a + seg->right_color.a) / 2.0); g_string_append_printf (string, "\t[%s color rgbt <%s, %s, %s, %s>]\n", buf, color_buf[0], color_buf[1], color_buf[2], color_buf[3]); /* Right */ g_ascii_formatd (buf, G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->right); g_ascii_formatd (color_buf[0], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->right_color.r); g_ascii_formatd (color_buf[1], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->right_color.g); g_ascii_formatd (color_buf[2], G_ASCII_DTOSTR_BUF_SIZE, "%f", seg->right_color.b); g_ascii_formatd (color_buf[3], G_ASCII_DTOSTR_BUF_SIZE, "%f", 1.0 - seg->right_color.a); g_string_append_printf (string, "\t[%s color rgbt <%s, %s, %s, %s>]\n", buf, color_buf[0], color_buf[1], color_buf[2], color_buf[3]); } g_string_append_printf (string, "} /* color_map */\n"); if (! g_output_stream_write_all (output, string->str, string->len, NULL, NULL, &my_error)) { GCancellable *cancellable = g_cancellable_new (); g_set_error (error, GIMP_DATA_ERROR, GIMP_DATA_ERROR_WRITE, _("Writing POV file '%s' failed: %s"), gimp_file_get_utf8_name (file), my_error->message); g_clear_error (&my_error); g_string_free (string, TRUE); /* Cancel the overwrite initiated by g_file_replace(). */ g_cancellable_cancel (cancellable); g_output_stream_close (output, cancellable, NULL); g_object_unref (cancellable); g_object_unref (output); return FALSE; } g_string_free (string, TRUE); g_object_unref (output); return TRUE; }
static GimpValueArray * xcf_save_invoker (GimpProcedure *procedure, Gimp *gimp, GimpContext *context, GimpProgress *progress, const GimpValueArray *args, GError **error) { XcfInfo info = { 0, }; GimpValueArray *return_vals; GimpImage *image; const gchar *uri; GFile *file; gboolean success = FALSE; GError *my_error = NULL; gimp_set_busy (gimp); image = gimp_value_get_image (gimp_value_array_index (args, 1), gimp); uri = g_value_get_string (gimp_value_array_index (args, 3)); file = g_file_new_for_uri (uri); info.output = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &my_error)); if (info.output) { gboolean compat_mode = gimp_image_get_xcf_compat_mode (image); info.gimp = gimp; info.seekable = G_SEEKABLE (info.output); info.progress = progress; info.file = file; if (compat_mode) info.compression = COMPRESS_RLE; else info.compression = COMPRESS_ZLIB; info.file_version = gimp_image_get_xcf_version (image, info.compression == COMPRESS_ZLIB, NULL, NULL); if (progress) gimp_progress_start (progress, FALSE, _("Saving '%s'"), gimp_file_get_utf8_name (file)); success = xcf_save_image (&info, image, &my_error); if (success) { if (progress) gimp_progress_set_text (progress, _("Closing '%s'"), gimp_file_get_utf8_name (file)); success = g_output_stream_close (info.output, NULL, &my_error); } if (! success) g_propagate_prefixed_error (error, my_error, _("Error writing '%s': "), gimp_file_get_utf8_name (file)); g_object_unref (info.output); if (progress) gimp_progress_end (progress); } else { g_propagate_prefixed_error (error, my_error, _("Error creating '%s': "), gimp_file_get_utf8_name (file)); } g_object_unref (file); return_vals = gimp_procedure_get_return_values (procedure, success, error ? *error : NULL); gimp_unset_busy (gimp); return return_vals; }
static GimpValueArray * xcf_load_invoker (GimpProcedure *procedure, Gimp *gimp, GimpContext *context, GimpProgress *progress, const GimpValueArray *args, GError **error) { XcfInfo info = { 0, }; GimpValueArray *return_vals; GimpImage *image = NULL; const gchar *uri; GFile *file; gboolean success = FALSE; gchar id[14]; GError *my_error = NULL; gimp_set_busy (gimp); uri = g_value_get_string (gimp_value_array_index (args, 1)); file = g_file_new_for_uri (uri); info.input = G_INPUT_STREAM (g_file_read (file, NULL, &my_error)); if (info.input) { info.gimp = gimp; info.seekable = G_SEEKABLE (info.input); info.progress = progress; info.file = file; info.compression = COMPRESS_NONE; if (progress) gimp_progress_start (progress, FALSE, _("Opening '%s'"), gimp_file_get_utf8_name (file)); success = TRUE; info.cp += xcf_read_int8 (info.input, (guint8 *) id, 14); if (! g_str_has_prefix (id, "gimp xcf ")) { success = FALSE; } else if (strcmp (id + 9, "file") == 0) { info.file_version = 0; } else if (id[9] == 'v') { info.file_version = atoi (id + 10); } else { success = FALSE; } if (success) { if (info.file_version >= 0 && info.file_version < G_N_ELEMENTS (xcf_loaders)) { image = (*(xcf_loaders[info.file_version])) (gimp, &info, error); if (! image) success = FALSE; } else { g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("XCF error: unsupported XCF file version %d " "encountered"), info.file_version); success = FALSE; } } g_object_unref (info.input); if (progress) gimp_progress_end (progress); } else { g_propagate_prefixed_error (error, my_error, _("Could not open '%s' for reading: "), gimp_file_get_utf8_name (file)); } g_object_unref (file); return_vals = gimp_procedure_get_return_values (procedure, success, error ? *error : NULL); if (success) gimp_value_set_image (gimp_value_array_index (return_vals, 1), image); gimp_unset_busy (gimp); return return_vals; }
/* called from the PDB (gimp_plugin_menu_register) */ gboolean gimp_plug_in_menu_register (GimpPlugIn *plug_in, const gchar *proc_name, const gchar *menu_path) { GimpPlugInProcedure *proc = NULL; GError *error = NULL; g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), FALSE); g_return_val_if_fail (proc_name != NULL, FALSE); g_return_val_if_fail (menu_path != NULL, FALSE); if (plug_in->plug_in_def) proc = gimp_plug_in_procedure_find (plug_in->plug_in_def->procedures, proc_name); if (! proc) proc = gimp_plug_in_procedure_find (plug_in->temp_procedures, proc_name); if (! proc) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Plug-in \"%s\"\n(%s)\n" "attempted to register the menu item \"%s\" " "for the procedure \"%s\".\n" "It has however not installed that procedure. This " "is not allowed.", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file), menu_path, proc_name); return FALSE; } switch (GIMP_PROCEDURE (proc)->proc_type) { case GIMP_INTERNAL: return FALSE; case GIMP_PLUGIN: case GIMP_EXTENSION: if (plug_in->call_mode != GIMP_PLUG_IN_CALL_QUERY && plug_in->call_mode != GIMP_PLUG_IN_CALL_INIT) return FALSE; case GIMP_TEMPORARY: break; } if (! proc->menu_label) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Plug-in \"%s\"\n(%s)\n" "attempted to register the menu item \"%s\" " "for procedure \"%s\".\n" "The menu label given in gimp_install_procedure() " "already contained a path. To make this work, " "pass just the menu's label to " "gimp_install_procedure().", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file), menu_path, proc_name); return FALSE; } if (! strlen (proc->menu_label)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Plug-in \"%s\"\n(%s)\n" "attempted to register the procedure \"%s\" " "in the menu \"%s\", but the procedure has no label. " "This is not allowed.", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file), proc_name, menu_path); return FALSE; } if (! gimp_plug_in_procedure_add_menu_path (proc, menu_path, &error)) { gimp_message_literal (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, error->message); g_clear_error (&error); return FALSE; } return TRUE; }
void gimp_action_history_init (Gimp *gimp) { GimpGuiConfig *config; GFile *file; GScanner *scanner; GTokenType token; gint count = 0; gint n_items = 0; g_return_if_fail (GIMP_IS_GIMP (gimp)); config = GIMP_GUI_CONFIG (gimp->config); if (history.items != NULL) { g_warning ("%s: must be run only once.", G_STRFUNC); return; } file = gimp_directory_file (GIMP_ACTION_HISTORY_FILENAME, NULL); if (gimp->be_verbose) g_print ("Parsing '%s'\n", gimp_file_get_utf8_name (file)); scanner = gimp_scanner_new_gfile (file, NULL); g_object_unref (file); if (! scanner) return; g_scanner_scope_add_symbol (scanner, 0, "history-item", GINT_TO_POINTER (HISTORY_ITEM)); token = G_TOKEN_LEFT_PAREN; while (g_scanner_peek_next_token (scanner) == token) { token = g_scanner_get_next_token (scanner); switch (token) { case G_TOKEN_LEFT_PAREN: token = G_TOKEN_SYMBOL; break; case G_TOKEN_SYMBOL: if (scanner->value.v_symbol == GINT_TO_POINTER (HISTORY_ITEM)) { gchar *action_name; token = G_TOKEN_STRING; if (g_scanner_peek_next_token (scanner) != token) break; if (! gimp_scanner_parse_string (scanner, &action_name)) break; token = G_TOKEN_INT; if (g_scanner_peek_next_token (scanner) != token || ! gimp_scanner_parse_int (scanner, &count)) { g_free (action_name); break; } history.items = g_list_insert_sorted (history.items, gimp_action_history_item_new (action_name, count), (GCompareFunc) gimp_action_history_init_compare_func); n_items++; g_free (action_name); } token = G_TOKEN_RIGHT_PAREN; break; case G_TOKEN_RIGHT_PAREN: token = G_TOKEN_LEFT_PAREN; if (n_items >= config->action_history_size) goto done; break; default: /* do nothing */ break; } } done: gimp_scanner_destroy (scanner); if (count > 1) { GList *actions; gint i; for (actions = history.items, i = 0; actions && i < config->action_history_size; actions = g_list_next (actions), i++) { GimpActionHistoryItem *action = actions->data; action->count -= count - 1; } } }
void session_save (Gimp *gimp, gboolean always_save) { GimpConfigWriter *writer; GFile *file; GError *error = NULL; g_return_if_fail (GIMP_IS_GIMP (gimp)); if (sessionrc_deleted && ! always_save) return; file = session_file (gimp); if (gimp->be_verbose) g_print ("Writing '%s'\n", gimp_file_get_utf8_name (file)); writer = gimp_config_writer_new_gfile (file, TRUE, "GIMP sessionrc\n\n" "This file takes session-specific info " "(that is info, you want to keep between " "two GIMP sessions). You are not supposed " "to edit it manually, but of course you " "can do. The sessionrc will be entirely " "rewritten every time you quit GIMP. " "If this file isn't found, defaults are " "used.", NULL); g_object_unref (file); if (!writer) return; gimp_dialog_factory_save (gimp_dialog_factory_get_singleton (), writer); gimp_config_writer_linefeed (writer); gimp_config_writer_open (writer, "hide-docks"); gimp_config_writer_identifier (writer, GIMP_GUI_CONFIG (gimp->config)->hide_docks ? "yes" : "no"); gimp_config_writer_close (writer); gimp_config_writer_open (writer, "single-window-mode"); gimp_config_writer_identifier (writer, GIMP_GUI_CONFIG (gimp->config)->single_window_mode ? "yes" : "no"); gimp_config_writer_close (writer); gimp_config_writer_open (writer, "show-tabs"); gimp_config_writer_printf (writer, GIMP_GUI_CONFIG (gimp->config)->show_tabs ? "yes" : "no"); gimp_config_writer_close (writer); gimp_config_writer_open (writer, "tabs-position"); gimp_config_writer_printf (writer, "%d", GIMP_GUI_CONFIG (gimp->config)->tabs_position); gimp_config_writer_close (writer); gimp_config_writer_open (writer, "last-tip-shown"); gimp_config_writer_printf (writer, "%d", GIMP_GUI_CONFIG (gimp->config)->last_tip_shown); gimp_config_writer_close (writer); if (! gimp_config_writer_finish (writer, "end of sessionrc", &error)) { gimp_message_literal (gimp, NULL, GIMP_MESSAGE_ERROR, error->message); g_clear_error (&error); } dialogs_save_recent_docks (gimp); sessionrc_deleted = FALSE; }
GList * gimp_palette_load_psp (GimpContext *context, GFile *file, GInputStream *input, GError **error) { GimpPalette *palette; gchar *palette_name; guchar color_bytes[4]; gint number_of_colors; gsize bytes_read; gint i, j; gboolean color_ok; gchar buffer[4096]; /*Maximum valid file size: 256 * 4 * 3 + 256 * 2 ~= 3650 bytes */ gchar **lines; gchar **ascii_colors; g_return_val_if_fail (G_IS_FILE (file), NULL); g_return_val_if_fail (G_IS_INPUT_STREAM (input), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); palette_name = g_path_get_basename (gimp_file_get_utf8_name (file)); palette = GIMP_PALETTE (gimp_palette_new (context, palette_name)); g_free (palette_name); if (! g_seekable_seek (G_SEEKABLE (input), 16, G_SEEK_SET, NULL, error)) { g_object_unref (palette); return NULL; } if (! g_input_stream_read_all (input, buffer, sizeof (buffer) - 1, &bytes_read, NULL, error)) { g_object_unref (palette); return NULL; } buffer[bytes_read] = '\0'; lines = g_strsplit (buffer, "\x0d\x0a", -1); number_of_colors = atoi (lines[0]); for (i = 0; i < number_of_colors; i++) { if (lines[i + 1] == NULL) { g_printerr ("Premature end of file reading %s.", gimp_file_get_utf8_name (file)); break; } ascii_colors = g_strsplit (lines[i + 1], " ", 3); color_ok = TRUE; for (j = 0 ; j < 3; j++) { if (ascii_colors[j] == NULL) { g_printerr ("Corrupted palette file %s.", gimp_file_get_utf8_name (file)); color_ok = FALSE; break; } color_bytes[j] = atoi (ascii_colors[j]); } if (color_ok) { GimpRGB color; gimp_rgba_set_uchar (&color, color_bytes[0], color_bytes[1], color_bytes[2], 255); gimp_palette_add_entry (palette, -1, NULL, &color); } g_strfreev (ascii_colors); } g_strfreev (lines); return g_list_prepend (NULL, palette); }
void session_init (Gimp *gimp) { GFile *file; GScanner *scanner; GTokenType token; GError *error = NULL; g_return_if_fail (GIMP_IS_GIMP (gimp)); file = session_file (gimp); scanner = gimp_scanner_new_gfile (file, &error); if (! scanner && error->code == GIMP_CONFIG_ERROR_OPEN_ENOENT) { g_clear_error (&error); g_object_unref (file); file = gimp_sysconf_directory_file ("sessionrc", NULL); scanner = gimp_scanner_new_gfile (file, NULL); } if (! scanner) { g_clear_error (&error); g_object_unref (file); return; } if (gimp->be_verbose) g_print ("Parsing '%s'\n", gimp_file_get_utf8_name (file)); g_scanner_scope_add_symbol (scanner, 0, "session-info", GINT_TO_POINTER (SESSION_INFO)); g_scanner_scope_add_symbol (scanner, 0, "hide-docks", GINT_TO_POINTER (HIDE_DOCKS)); g_scanner_scope_add_symbol (scanner, 0, "single-window-mode", GINT_TO_POINTER (SINGLE_WINDOW_MODE)); g_scanner_scope_add_symbol (scanner, 0, "show-tabs", GINT_TO_POINTER (SHOW_TABS)); g_scanner_scope_add_symbol (scanner, 0, "tabs-position", GINT_TO_POINTER (TABS_POSITION)); g_scanner_scope_add_symbol (scanner, 0, "last-tip-shown", GINT_TO_POINTER (LAST_TIP_SHOWN)); token = G_TOKEN_LEFT_PAREN; while (g_scanner_peek_next_token (scanner) == token) { token = g_scanner_get_next_token (scanner); switch (token) { case G_TOKEN_LEFT_PAREN: token = G_TOKEN_SYMBOL; break; case G_TOKEN_SYMBOL: if (scanner->value.v_symbol == GINT_TO_POINTER (SESSION_INFO)) { GimpDialogFactory *factory = NULL; GimpSessionInfo *info = NULL; gchar *factory_name = NULL; gchar *entry_name = NULL; GimpDialogFactoryEntry *entry = NULL; token = G_TOKEN_STRING; if (! gimp_scanner_parse_string (scanner, &factory_name)) break; /* In versions <= GIMP 2.6 there was a "toolbox", a * "dock", a "display" and a "toplevel" factory. These * are now merged to a single gimp_dialog_factory_get_singleton (). We * need the legacy name though, so keep it around. */ factory = gimp_dialog_factory_get_singleton (); info = gimp_session_info_new (); /* GIMP 2.6 has the entry name as part of the * session-info header, so try to get it */ gimp_scanner_parse_string (scanner, &entry_name); if (entry_name) { /* Previously, GimpDock was a toplevel. That is why * versions <= GIMP 2.6 has "dock" as the entry name. We * want "dock" to be interpreted as 'dock window' * however so have some special-casing for that. When * the entry name is "dock" the factory name is either * "dock" or "toolbox". */ if (strcmp (entry_name, "dock") == 0) { entry = gimp_dialog_factory_find_entry (factory, (strcmp (factory_name, "toolbox") == 0 ? "gimp-toolbox-window" : "gimp-dock-window")); } else { entry = gimp_dialog_factory_find_entry (factory, entry_name); } } /* We're done with these now */ g_free (factory_name); g_free (entry_name); /* We can get the factory entry either now (the GIMP <= * 2.6 way), or when we deserialize (the GIMP 2.8 way) */ if (entry) { gimp_session_info_set_factory_entry (info, entry); } /* Always try to deserialize */ if (gimp_config_deserialize (GIMP_CONFIG (info), scanner, 1, NULL)) { /* Make sure we got a factory entry either the 2.6 * or 2.8 way */ if (gimp_session_info_get_factory_entry (info)) { GIMP_LOG (DIALOG_FACTORY, "successfully parsed and added session info %p", info); gimp_dialog_factory_add_session_info (factory, info); } else { GIMP_LOG (DIALOG_FACTORY, "failed to parse session info %p, not adding", info); } g_object_unref (info); } else { g_object_unref (info); /* set token to left paren to we won't set another * error below, gimp_config_deserialize() already did */ token = G_TOKEN_LEFT_PAREN; goto error; } } else if (scanner->value.v_symbol == GINT_TO_POINTER (HIDE_DOCKS)) { gboolean hide_docks; token = G_TOKEN_IDENTIFIER; if (! gimp_scanner_parse_boolean (scanner, &hide_docks)) break; g_object_set (gimp->config, "hide-docks", hide_docks, NULL); } else if (scanner->value.v_symbol == GINT_TO_POINTER (SINGLE_WINDOW_MODE)) { gboolean single_window_mode; token = G_TOKEN_IDENTIFIER; if (! gimp_scanner_parse_boolean (scanner, &single_window_mode)) break; g_object_set (gimp->config, "single-window-mode", single_window_mode, NULL); } else if (scanner->value.v_symbol == GINT_TO_POINTER (SHOW_TABS)) { gboolean show_tabs; token = G_TOKEN_IDENTIFIER; if (! gimp_scanner_parse_boolean (scanner, &show_tabs)) break; g_object_set (gimp->config, "show-tabs", show_tabs, NULL); } else if (scanner->value.v_symbol == GINT_TO_POINTER (TABS_POSITION)) { gint tabs_position; token = G_TOKEN_INT; if (! gimp_scanner_parse_int (scanner, &tabs_position)) break; g_object_set (gimp->config, "tabs-position", tabs_position, NULL); } else if (scanner->value.v_symbol == GINT_TO_POINTER (LAST_TIP_SHOWN)) { gint last_tip_shown; token = G_TOKEN_INT; if (! gimp_scanner_parse_int (scanner, &last_tip_shown)) break; g_object_set (gimp->config, "last-tip-shown", last_tip_shown, NULL); } token = G_TOKEN_RIGHT_PAREN; break; case G_TOKEN_RIGHT_PAREN: token = G_TOKEN_LEFT_PAREN; break; default: /* do nothing */ break; } } error: if (token != G_TOKEN_LEFT_PAREN) { g_scanner_get_next_token (scanner); g_scanner_unexp_token (scanner, token, NULL, NULL, NULL, _("fatal parse error"), TRUE); } if (error) { gimp_message_literal (gimp, NULL, GIMP_MESSAGE_ERROR, error->message); g_clear_error (&error); gimp_config_file_backup_on_error (file, "sessionrc", NULL); } gimp_scanner_destroy (scanner); g_object_unref (file); dialogs_load_recent_docks (gimp); }
GList * gimp_palette_load_aco (GimpContext *context, GFile *file, GInputStream *input, GError **error) { GimpPalette *palette; gchar *palette_name; gint format_version; gint number_of_colors; gint i; gchar header[4]; gsize bytes_read; g_return_val_if_fail (G_IS_FILE (file), NULL); g_return_val_if_fail (G_IS_INPUT_STREAM (input), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); if (! g_input_stream_read_all (input, header, sizeof (header), &bytes_read, NULL, error) || bytes_read != sizeof (header)) { g_prefix_error (error, _("Could not read header from palette file '%s': "), gimp_file_get_utf8_name (file)); return NULL; } palette_name = g_path_get_basename (gimp_file_get_utf8_name (file)); palette = GIMP_PALETTE (gimp_palette_new (context, palette_name)); g_free (palette_name); format_version = header[1] + (header[0] << 8); number_of_colors = header[3] + (header[2] << 8); for (i = 0; i < number_of_colors; i++) { gchar color_info[10]; gint color_space; gint w, x, y, z; gboolean color_ok = FALSE; GimpRGB color; GError *my_error = NULL; if (! g_input_stream_read_all (input, color_info, sizeof (color_info), &bytes_read, NULL, &my_error) || bytes_read != sizeof (color_info)) { if (palette->colors) { g_message (_("Reading palette file '%s': " "Read %d colors from truncated file: %s"), gimp_file_get_utf8_name (file), g_list_length (palette->colors), my_error ? my_error->message : _("Premature end of file.")); g_clear_error (&my_error); break; } g_propagate_error (error, my_error); g_object_unref (palette); return NULL; } color_space = color_info[1] + (color_info[0] << 8); w = (guchar) color_info[3] + ((guchar) color_info[2] << 8); x = (guchar) color_info[5] + ((guchar) color_info[4] << 8); y = (guchar) color_info[7] + ((guchar) color_info[6] << 8); z = (guchar) color_info[9] + ((guchar) color_info[8] << 8); if (color_space == 0) /* RGB */ { gdouble R = ((gdouble) w) / 65536.0; gdouble G = ((gdouble) x) / 65536.0; gdouble B = ((gdouble) y) / 65536.0; gimp_rgba_set (&color, R, G, B, 1.0); color_ok = TRUE; } else if (color_space == 1) /* HSV */ { GimpHSV hsv; gdouble H = ((gdouble) w) / 65536.0; gdouble S = ((gdouble) x) / 65536.0; gdouble V = ((gdouble) y) / 65536.0; gimp_hsva_set (&hsv, H, S, V, 1.0); gimp_hsv_to_rgb (&hsv, &color); color_ok = TRUE; } else if (color_space == 2) /* CMYK */ { GimpCMYK cmyk; gdouble C = 1.0 - (((gdouble) w) / 65536.0); gdouble M = 1.0 - (((gdouble) x) / 65536.0); gdouble Y = 1.0 - (((gdouble) y) / 65536.0); gdouble K = 1.0 - (((gdouble) z) / 65536.0); gimp_cmyka_set (&cmyk, C, M, Y, K, 1.0); gimp_cmyk_to_rgb (&cmyk, &color); color_ok = TRUE; } else if (color_space == 8) /* Grayscale */ { gdouble K = 1.0 - (((gdouble) w) / 10000.0); gimp_rgba_set (&color, K, K, K, 1.0); color_ok = TRUE; } else if (color_space == 9) /* Wide? CMYK */ { GimpCMYK cmyk; gdouble C = 1.0 - (((gdouble) w) / 10000.0); gdouble M = 1.0 - (((gdouble) x) / 10000.0); gdouble Y = 1.0 - (((gdouble) y) / 10000.0); gdouble K = 1.0 - (((gdouble) z) / 10000.0); gimp_cmyka_set (&cmyk, C, M, Y, K, 1.0); gimp_cmyk_to_rgb (&cmyk, &color); color_ok = TRUE; } else { g_printerr ("Unsupported color space (%d) in ACO file %s\n", color_space, gimp_file_get_utf8_name (file)); } if (format_version == 2) { gchar format2_preamble[4]; gint number_of_chars; if (! g_input_stream_read_all (input, format2_preamble, sizeof (format2_preamble), &bytes_read, NULL, error) || bytes_read != sizeof (format2_preamble)) { g_object_unref (palette); return NULL; } number_of_chars = format2_preamble[3] + (format2_preamble[2] << 8); if (! g_seekable_seek (G_SEEKABLE (input), number_of_chars * 2, G_SEEK_SET, NULL, error)) { g_object_unref (palette); return NULL; } } if (color_ok) gimp_palette_add_entry (palette, -1, NULL, &color); } return g_list_prepend (NULL, palette); }
static void gimp_plug_in_manager_add_from_rc (GimpPlugInManager *manager, GimpPlugInDef *plug_in_def) { GSList *list; gchar *path1; gchar *basename1; g_return_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager)); g_return_if_fail (plug_in_def != NULL); g_return_if_fail (plug_in_def->file != NULL); path1 = g_file_get_path (plug_in_def->file); if (! g_path_is_absolute (path1)) { g_warning ("plug_ins_def_add_from_rc: filename not absolute (skipping)"); g_object_unref (plug_in_def); g_free (path1); return; } basename1 = g_path_get_basename (path1); /* If this is a file load or save plugin, make sure we have * something for one of the extensions, prefixes, or magic number. * Other bits of code rely on detecting file plugins by the * presence of one of these things, but the raw plug-in needs to be * able to register no extensions, prefixes or magics. */ for (list = plug_in_def->procedures; list; list = list->next) { GimpPlugInProcedure *proc = list->data; if (! proc->extensions && ! proc->prefixes && ! proc->magics && proc->menu_paths && (g_str_has_prefix (proc->menu_paths->data, "<Load>") || g_str_has_prefix (proc->menu_paths->data, "<Save>"))) { proc->extensions = g_strdup (""); } } /* Check if the entry mentioned in pluginrc matches an executable * found in the plug_in_path. */ for (list = manager->plug_in_defs; list; list = list->next) { GimpPlugInDef *ondisk_plug_in_def = list->data; gchar *path2; gchar *basename2; path2 = g_file_get_path (ondisk_plug_in_def->file); basename2 = g_path_get_basename (path2); g_free (path2); if (! strcmp (basename1, basename2)) { if (g_file_equal (plug_in_def->file, ondisk_plug_in_def->file) && (plug_in_def->mtime == ondisk_plug_in_def->mtime)) { /* Use pluginrc entry, deleting on-disk entry */ list->data = plug_in_def; g_object_unref (ondisk_plug_in_def); } else { /* Use on-disk entry, deleting pluginrc entry */ g_object_unref (plug_in_def); } g_free (basename2); g_free (basename1); g_free (path1); return; } g_free (basename2); } g_free (basename1); g_free (path1); manager->write_pluginrc = TRUE; if (manager->gimp->be_verbose) { g_printerr ("pluginrc lists '%s', but it wasn't found\n", gimp_file_get_utf8_name (plug_in_def->file)); } g_object_unref (plug_in_def); }
GimpPaletteFileFormat gimp_palette_load_detect_format (GFile *file, GInputStream *input) { GimpPaletteFileFormat format = GIMP_PALETTE_FILE_FORMAT_UNKNOWN; gchar header[16]; gsize bytes_read; if (g_input_stream_read_all (input, &header, sizeof (header), &bytes_read, NULL, NULL) && bytes_read == sizeof (header)) { if (g_str_has_prefix (header + 0, "RIFF") && g_str_has_prefix (header + 8, "PAL data")) { format = GIMP_PALETTE_FILE_FORMAT_RIFF_PAL; } else if (g_str_has_prefix (header, "GIMP Palette")) { format = GIMP_PALETTE_FILE_FORMAT_GPL; } else if (g_str_has_prefix (header, "JASC-PAL")) { format = GIMP_PALETTE_FILE_FORMAT_PSP_PAL; } } if (format == GIMP_PALETTE_FILE_FORMAT_UNKNOWN) { gchar *lower = g_ascii_strdown (gimp_file_get_utf8_name (file), -1); if (g_str_has_suffix (lower, ".aco")) { format = GIMP_PALETTE_FILE_FORMAT_ACO; } else if (g_str_has_suffix (lower, ".css")) { format = GIMP_PALETTE_FILE_FORMAT_CSS; } g_free (lower); } if (format == GIMP_PALETTE_FILE_FORMAT_UNKNOWN) { GFileInfo *info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, NULL, NULL); if (info) { goffset size = g_file_info_get_size (info); if (size == 768) format = GIMP_PALETTE_FILE_FORMAT_ACT; g_object_unref (info); } } g_seekable_seek (G_SEEKABLE (input), 0, G_SEEK_SET, NULL, NULL); return format; }
void gimp_plug_in_manager_restore (GimpPlugInManager *manager, GimpContext *context, GimpInitStatusFunc status_callback) { Gimp *gimp; GFile *pluginrc; GSList *list; GError *error = NULL; g_return_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager)); g_return_if_fail (GIMP_IS_CONTEXT (context)); g_return_if_fail (status_callback != NULL); gimp = manager->gimp; /* need a GimpPDBContext for calling gimp_plug_in_manager_run_foo() */ context = gimp_pdb_context_new (gimp, context, TRUE); /* search for binaries in the plug-in directory path */ gimp_plug_in_manager_search (manager, status_callback); /* read the pluginrc file for cached data */ pluginrc = gimp_plug_in_manager_get_pluginrc (manager); gimp_plug_in_manager_read_pluginrc (manager, pluginrc, status_callback); /* query any plug-ins that changed since we last wrote out pluginrc */ gimp_plug_in_manager_query_new (manager, context, status_callback); /* initialize the plug-ins */ gimp_plug_in_manager_init_plug_ins (manager, context, status_callback); /* add the procedures to manager->plug_in_procedures */ for (list = manager->plug_in_defs; list; list = list->next) { GimpPlugInDef *plug_in_def = list->data; GSList *list2; for (list2 = plug_in_def->procedures; list2; list2 = list2->next) { gimp_plug_in_manager_add_procedure (manager, list2->data); } } /* write the pluginrc file if necessary */ if (manager->write_pluginrc) { if (gimp->be_verbose) g_print ("Writing '%s'\n", gimp_file_get_utf8_name (pluginrc)); if (! plug_in_rc_write (manager->plug_in_defs, pluginrc, &error)) { gimp_message_literal (gimp, NULL, GIMP_MESSAGE_ERROR, error->message); g_clear_error (&error); } manager->write_pluginrc = FALSE; } g_object_unref (pluginrc); /* create locale and help domain lists */ for (list = manager->plug_in_defs; list; list = list->next) { GimpPlugInDef *plug_in_def = list->data; if (plug_in_def->locale_domain_name) gimp_plug_in_manager_add_locale_domain (manager, plug_in_def->file, plug_in_def->locale_domain_name, plug_in_def->locale_domain_path); else /* set the default plug-in locale domain */ gimp_plug_in_def_set_locale_domain (plug_in_def, gimp_plug_in_manager_get_locale_domain (manager, plug_in_def->file, NULL), NULL); if (plug_in_def->help_domain_name) gimp_plug_in_manager_add_help_domain (manager, plug_in_def->file, plug_in_def->help_domain_name, plug_in_def->help_domain_uri); } /* we're done with the plug-in-defs */ g_slist_free_full (manager->plug_in_defs, (GDestroyNotify) g_object_unref); manager->plug_in_defs = NULL; /* bind plug-in text domains */ gimp_plug_in_manager_bind_text_domains (manager); /* add the plug-in procs to the procedure database */ for (list = manager->plug_in_procedures; list; list = list->next) { gimp_plug_in_manager_add_to_db (manager, context, list->data); } /* sort the load, save and export procedures */ manager->load_procs = g_slist_sort_with_data (manager->load_procs, gimp_plug_in_manager_file_proc_compare, manager); manager->save_procs = g_slist_sort_with_data (manager->save_procs, gimp_plug_in_manager_file_proc_compare, manager); manager->export_procs = g_slist_sort_with_data (manager->export_procs, gimp_plug_in_manager_file_proc_compare, manager); gimp_plug_in_manager_run_extensions (manager, context, status_callback); g_object_unref (context); }
void color_history_restore (Gimp *gimp) { GFile *file; GScanner *scanner; GTokenType token; g_return_if_fail (GIMP_IS_GIMP (gimp)); file = gimp_personal_rc_gfile ("colorrc"); if (gimp->be_verbose) g_print ("Parsing '%s'\n", gimp_file_get_utf8_name (file)); scanner = gimp_scanner_new_gfile (file, NULL); g_object_unref (file); if (! scanner) return; g_scanner_scope_add_symbol (scanner, 0, "color-history", GINT_TO_POINTER (COLOR_HISTORY)); token = G_TOKEN_LEFT_PAREN; while (g_scanner_peek_next_token (scanner) == token) { token = g_scanner_get_next_token (scanner); switch (token) { case G_TOKEN_LEFT_PAREN: token = G_TOKEN_SYMBOL; break; case G_TOKEN_SYMBOL: if (scanner->value.v_symbol == GINT_TO_POINTER (COLOR_HISTORY)) { while (g_scanner_peek_next_token (scanner) == G_TOKEN_LEFT_PAREN) { GimpRGB color; if (! gimp_scanner_parse_color (scanner, &color)) goto error; color_history_add_from_rc (&color); } } token = G_TOKEN_RIGHT_PAREN; break; case G_TOKEN_RIGHT_PAREN: token = G_TOKEN_LEFT_PAREN; break; default: /* do nothing */ break; } } error: gimp_scanner_destroy (scanner); }
GimpImage * file_open_with_proc_and_display (Gimp *gimp, GimpContext *context, GimpProgress *progress, GFile *file, GFile *entered_file, gboolean as_new, GimpPlugInProcedure *file_proc, GObject *screen, gint monitor, GimpPDBStatusType *status, GError **error) { GimpImage *image; const gchar *mime_type = NULL; g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL); g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL); g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL); g_return_val_if_fail (G_IS_FILE (file), NULL); g_return_val_if_fail (G_IS_FILE (entered_file), NULL); g_return_val_if_fail (screen == NULL || G_IS_OBJECT (screen), NULL); g_return_val_if_fail (status != NULL, NULL); image = file_open_image (gimp, context, progress, file, entered_file, as_new, file_proc, GIMP_RUN_INTERACTIVE, status, &mime_type, error); if (image) { /* If the file was imported we want to set the layer name to the * file name. For now, assume that multi-layered imported images * have named the layers already, so only rename the layer of * single-layered imported files. Note that this will also * rename already named layers from e.g. single-layered PSD * files. To solve this properly, we would need new file plug-in * API. */ if (! file_proc) file_proc = gimp_image_get_load_proc (image); if (file_open_file_proc_is_import (file_proc) && gimp_image_get_n_layers (image) == 1) { GimpObject *layer = gimp_image_get_layer_iter (image)->data; gchar *basename; basename = g_path_get_basename (gimp_file_get_utf8_name (file)); gimp_item_rename (GIMP_ITEM (layer), basename, NULL); gimp_image_undo_free (image); gimp_image_clean_all (image); g_free (basename); } if (gimp_create_display (image->gimp, image, GIMP_UNIT_PIXEL, 1.0, screen, monitor)) { /* the display owns the image now */ g_object_unref (image); } if (! as_new) { GimpDocumentList *documents = GIMP_DOCUMENT_LIST (gimp->documents); GimpImagefile *imagefile; GFile *any_file; imagefile = gimp_document_list_add_file (documents, file, mime_type); /* can only create a thumbnail if the passed file and the * resulting image's file match. Use any_file() here so we * create thumbnails for both XCF and imported images. */ any_file = gimp_image_get_any_file (image); if (any_file && g_file_equal (file, any_file)) { /* no need to save a thumbnail if there's a good one already */ if (! gimp_imagefile_check_thumbnail (imagefile)) { gimp_imagefile_save_thumbnail (imagefile, mime_type, image, NULL); } } } /* announce that we opened this image */ gimp_image_opened (image->gimp, file); } return image; }
/** * gimp_scanner_new_stream: * @input: a #GInputStream * @error: return location for #GError, or %NULL * * Return value: The new #GScanner. * * Since: 2.10 **/ GScanner * gimp_scanner_new_stream (GInputStream *input, GError **error) { GScanner *scanner; GFile *file; const gchar *path; GString *string; gchar buffer[4096]; gsize bytes_read; g_return_val_if_fail (G_IS_INPUT_STREAM (input), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); file = g_object_get_data (G_OBJECT (input), "gimp-file"); if (file) path = gimp_file_get_utf8_name (file); else path = "stream"; string = g_string_new (NULL); do { GError *my_error = NULL; gboolean success; success = g_input_stream_read_all (input, buffer, sizeof (buffer), &bytes_read, NULL, &my_error); if (bytes_read > 0) g_string_append_len (string, buffer, bytes_read); if (! success) { if (string->len > 0) { g_printerr ("%s: read error in '%s', trying to scan " "partial content: %s", G_STRFUNC, path, my_error->message); g_clear_error (&my_error); break; } g_string_free (string, TRUE); g_propagate_error (error, my_error); return NULL; } } while (bytes_read == sizeof (buffer)); /* gimp_scanner_new() takes a "name" for the scanner, not a filename */ scanner = gimp_scanner_new (path, NULL, string->str, error); bytes_read = string->len; g_scanner_input_text (scanner, g_string_free (string, FALSE), bytes_read); return scanner; }
GList * file_open_layers (Gimp *gimp, GimpContext *context, GimpProgress *progress, GimpImage *dest_image, gboolean merge_visible, GFile *file, GimpRunMode run_mode, GimpPlugInProcedure *file_proc, GimpPDBStatusType *status, GError **error) { GimpImage *new_image; GList *layers = NULL; const gchar *mime_type = NULL; g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL); g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL); g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), NULL); g_return_val_if_fail (GIMP_IS_IMAGE (dest_image), NULL); g_return_val_if_fail (G_IS_FILE (file), NULL); g_return_val_if_fail (status != NULL, NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); new_image = file_open_image (gimp, context, progress, file, file, FALSE, file_proc, run_mode, status, &mime_type, error); if (new_image) { gint n_visible = 0; gimp_image_undo_disable (new_image); layers = file_open_get_layers (new_image, merge_visible, &n_visible); if (merge_visible && n_visible > 1) { GimpLayer *layer; g_list_free (layers); layer = gimp_image_merge_visible_layers (new_image, context, GIMP_CLIP_TO_IMAGE, FALSE, FALSE); layers = g_list_prepend (NULL, layer); } if (layers) { gchar *basename; basename = g_path_get_basename (gimp_file_get_utf8_name (file)); file_open_convert_items (dest_image, basename, layers); g_free (basename); gimp_document_list_add_file (GIMP_DOCUMENT_LIST (gimp->documents), file, mime_type); } else { g_set_error_literal (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Image doesn't contain any layers")); *status = GIMP_PDB_EXECUTION_ERROR; } g_object_unref (new_image); } return g_list_reverse (layers); }
void gimp_export_dialog_set_image (GimpExportDialog *dialog, Gimp *gimp, GimpImage *image) { GFile *dir_file = NULL; GFile *name_file = NULL; GFile *ext_file = NULL; gchar *basename; g_return_if_fail (GIMP_IS_EXPORT_DIALOG (dialog)); g_return_if_fail (GIMP_IS_IMAGE (image)); GIMP_FILE_DIALOG (dialog)->image = image; gimp_file_dialog_set_file_proc (GIMP_FILE_DIALOG (dialog), NULL); /* * Priority of default paths for Export: * * 1. Last Export path * 2. Path of import source * 3. Path of XCF source * 4. Last path of any save to XCF * 5. Last Export path of any document * 6. The default path (usually the OS 'Documents' path) */ dir_file = gimp_image_get_exported_file (image); if (! dir_file) dir_file = g_object_get_data (G_OBJECT (image), "gimp-image-source-file"); if (! dir_file) dir_file = gimp_image_get_imported_file (image); if (! dir_file) dir_file = gimp_image_get_file (image); if (! dir_file) dir_file = g_object_get_data (G_OBJECT (gimp), GIMP_FILE_SAVE_LAST_FILE_KEY); if (! dir_file) dir_file = g_object_get_data (G_OBJECT (gimp), GIMP_FILE_EXPORT_LAST_FILE_KEY); if (! dir_file) dir_file = gimp_export_dialog_get_default_folder (gimp); /* Priority of default basenames for Export: * * 1. Last Export name * 3. Save URI * 2. Source file name * 3. 'Untitled' */ name_file = gimp_image_get_exported_file (image); if (! name_file) name_file = gimp_image_get_file (image); if (! name_file) name_file = gimp_image_get_imported_file (image); if (! name_file) name_file = gimp_image_get_untitled_file (image); /* Priority of default type/extension for Export: * * 1. Type of last Export * 2. Type of the image Import * 3. Type of latest Export of any document * 4. .png */ ext_file = gimp_image_get_exported_file (image); if (! ext_file) ext_file = gimp_image_get_imported_file (image); if (! ext_file) ext_file = g_object_get_data (G_OBJECT (gimp), GIMP_FILE_EXPORT_LAST_FILE_KEY); if (ext_file) g_object_ref (ext_file); else ext_file = g_file_new_for_uri ("file:///we/only/care/about/extension.png"); if (ext_file) { GFile *tmp_file = file_utils_file_with_new_ext (name_file, ext_file); basename = g_path_get_basename (gimp_file_get_utf8_name (tmp_file)); g_object_unref (tmp_file); g_object_unref (ext_file); } else { basename = g_path_get_basename (gimp_file_get_utf8_name (name_file)); } if (g_file_query_file_type (dir_file, G_FILE_QUERY_INFO_NONE, NULL) == G_FILE_TYPE_DIRECTORY) { gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (dialog), dir_file, NULL); } else { GFile *parent_file = g_file_get_parent (dir_file); gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (dialog), parent_file, NULL); g_object_unref (parent_file); } gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), basename); }
/** * gimp_color_profile_new_from_file: * @file: a #GFile * @error: return location for #GError * * This function opens an ICC color profile from @file. * * Return value: the #GimpColorProfile, or %NULL. On error, %NULL is * returned and @error is set. * * Since: 2.10 **/ GimpColorProfile * gimp_color_profile_new_from_file (GFile *file, GError **error) { GimpColorProfile *profile = NULL; cmsHPROFILE lcms_profile = NULL; guint8 *data = NULL; gsize length = 0; gchar *path; g_return_val_if_fail (G_IS_FILE (file), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); path = g_file_get_path (file); if (path) { GMappedFile *mapped; mapped = g_mapped_file_new (path, FALSE, error); if (! mapped) return NULL; length = g_mapped_file_get_length (mapped); data = g_memdup (g_mapped_file_get_contents (mapped), length); lcms_profile = cmsOpenProfileFromMem (data, length); g_mapped_file_unref (mapped); } else { GFileInfo *info; info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, NULL, error); if (info) { GInputStream *input; length = g_file_info_get_size (info); data = g_malloc (length); g_object_unref (info); input = G_INPUT_STREAM (g_file_read (file, NULL, error)); if (input) { gsize bytes_read; if (g_input_stream_read_all (input, data, length, &bytes_read, NULL, error) && bytes_read == length) { lcms_profile = cmsOpenProfileFromMem (data, length); } g_object_unref (input); } } } if (lcms_profile) { profile = g_object_new (GIMP_TYPE_COLOR_PROFILE, NULL); profile->priv->lcms_profile = lcms_profile; profile->priv->data = data; profile->priv->length = length; } else { if (data) g_free (data); if (error && *error == NULL) { g_set_error (error, gimp_color_profile_error_quark (), 0, _("'%s' does not appear to be an ICC color profile"), gimp_file_get_utf8_name (file)); } } return profile; }
void gimp_tools_restore (Gimp *gimp) { GimpContainer *gimp_list; GimpObject *object; GFile *file; GList *list; GError *error = NULL; g_return_if_fail (GIMP_IS_GIMP (gimp)); gimp_list = gimp_list_new (GIMP_TYPE_TOOL_INFO, FALSE); file = gimp_directory_file ("toolrc", NULL); if (gimp->be_verbose) g_print ("Parsing '%s'\n", gimp_file_get_utf8_name (file)); if (gimp_config_deserialize_gfile (GIMP_CONFIG (gimp_list), file, NULL, NULL)) { gint n = gimp_container_get_n_children (gimp->tool_info_list); gint i; gimp_list_reverse (GIMP_LIST (gimp_list)); for (list = GIMP_LIST (gimp_list)->list, i = 0; list; list = g_list_next (list), i++) { const gchar *name; name = gimp_object_get_name (list->data); object = gimp_container_get_child_by_name (gimp->tool_info_list, name); if (object) { g_object_set (object, "visible", GIMP_TOOL_INFO (list->data)->visible, NULL); gimp_container_reorder (gimp->tool_info_list, object, MIN (i, n - 1)); } } } g_object_unref (file); g_object_unref (gimp_list); /* make the generic operation tool invisible by default */ object = gimp_container_get_child_by_name (gimp->tool_info_list, "gimp-operation-tool"); if (object) g_object_set (object, "visible", FALSE, NULL); for (list = gimp_get_tool_info_iter (gimp); list; list = g_list_next (list)) { GimpToolInfo *tool_info = GIMP_TOOL_INFO (list->data); /* get default values from prefs (see bug #120832) */ gimp_config_reset (GIMP_CONFIG (tool_info->tool_options)); } if (! gimp_contexts_load (gimp, &error)) { gimp_message_literal (gimp, NULL, GIMP_MESSAGE_WARNING, error->message); g_clear_error (&error); } /* make sure there is always a tool active, so broken config files * can't leave us with no initial tool */ if (! gimp_context_get_tool (gimp_get_user_context (gimp))) { gimp_context_set_tool (gimp_get_user_context (gimp), gimp_get_tool_info_iter (gimp)->data); } for (list = gimp_get_tool_info_iter (gimp); list; list = g_list_next (list)) { GimpToolInfo *tool_info = GIMP_TOOL_INFO (list->data); GimpToolOptionsGUIFunc options_gui_func; GtkWidget *options_gui; /* copy all context properties except those the tool actually * uses, because the subsequent deserialize() on the tool * options will only set the properties that were set to * non-default values at the time of saving, and we want to * keep these default values as if they have been saved. * (see bug #541586). */ gimp_context_copy_properties (gimp_get_user_context (gimp), GIMP_CONTEXT (tool_info->tool_options), GIMP_CONTEXT_PROP_MASK_ALL &~ (tool_info->context_props | GIMP_CONTEXT_PROP_MASK_TOOL | GIMP_CONTEXT_PROP_MASK_PAINT_INFO)); gimp_tool_options_deserialize (tool_info->tool_options, NULL); options_gui_func = g_object_get_data (G_OBJECT (tool_info), "gimp-tool-options-gui-func"); if (options_gui_func) { options_gui = (* options_gui_func) (tool_info->tool_options); } else { GtkWidget *label; options_gui = gimp_tool_options_gui (tool_info->tool_options); label = gtk_label_new (_("This tool has\nno options.")); gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER); gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC, -1); gtk_box_pack_start (GTK_BOX (options_gui), label, FALSE, FALSE, 6); gtk_widget_show (label); } gimp_tools_set_tool_options_gui (tool_info->tool_options, g_object_ref_sink (options_gui)); } }
void gimp_plug_in_close (GimpPlugIn *plug_in, gboolean kill_it) { g_return_if_fail (GIMP_IS_PLUG_IN (plug_in)); g_return_if_fail (plug_in->open); plug_in->open = FALSE; if (plug_in->pid) { #ifndef G_OS_WIN32 gint status; #endif /* Ask the filter to exit gracefully, but not if it is closed because of a broken pipe. */ if (kill_it && ! plug_in->hup) { gp_quit_write (plug_in->my_write, plug_in); /* give the plug-in some time (10 ms) */ g_usleep (10000); } /* If necessary, kill the filter. */ #ifndef G_OS_WIN32 if (kill_it) { if (plug_in->manager->gimp->be_verbose) g_print ("Terminating plug-in: '%s'\n", gimp_file_get_utf8_name (plug_in->file)); /* If the plug-in opened a process group, kill the group instead * of only the plug-in, so we kill the plug-in's children too */ if (getpgid (0) != getpgid (plug_in->pid)) status = kill (- plug_in->pid, SIGKILL); else status = kill (plug_in->pid, SIGKILL); } /* Wait for the process to exit. This will happen * immediately if it was just killed. */ waitpid (plug_in->pid, &status, 0); #else /* G_OS_WIN32 */ if (kill_it) { /* Trying to avoid TerminateProcess (does mostly work). * Otherwise some of our needed DLLs may get into an * unstable state (see Win32 API docs). */ DWORD dwExitCode = STILL_ACTIVE; DWORD dwTries = 10; while (dwExitCode == STILL_ACTIVE && GetExitCodeProcess ((HANDLE) plug_in->pid, &dwExitCode) && (dwTries > 0)) { Sleep (10); dwTries--; } if (dwExitCode == STILL_ACTIVE) { if (plug_in->manager->gimp->be_verbose) g_print ("Terminating plug-in: '%s'\n", gimp_file_get_utf8_name (plug_in->file)); TerminateProcess ((HANDLE) plug_in->pid, 0); } } #endif /* G_OS_WIN32 */ g_spawn_close_pid (plug_in->pid); plug_in->pid = 0; } /* Remove the input handler. */ if (plug_in->input_id) { g_source_remove (plug_in->input_id); plug_in->input_id = 0; } /* Close the pipes. */ if (plug_in->my_read != NULL) { g_io_channel_unref (plug_in->my_read); plug_in->my_read = NULL; } if (plug_in->my_write != NULL) { g_io_channel_unref (plug_in->my_write); plug_in->my_write = NULL; } if (plug_in->his_read != NULL) { g_io_channel_unref (plug_in->his_read); plug_in->his_read = NULL; } if (plug_in->his_write != NULL) { g_io_channel_unref (plug_in->his_write); plug_in->his_write = NULL; } gimp_wire_clear_error (); while (plug_in->temp_proc_frames) { GimpPlugInProcFrame *proc_frame = plug_in->temp_proc_frames->data; #ifdef GIMP_UNSTABLE g_printerr ("plug-in '%s' aborted before sending its " "temporary procedure return values\n", gimp_object_get_name (plug_in)); #endif if (proc_frame->main_loop && g_main_loop_is_running (proc_frame->main_loop)) { g_main_loop_quit (proc_frame->main_loop); } /* pop the frame here, because normally this only happens in * gimp_plug_in_handle_temp_proc_return(), which can't * be called after plug_in_close() */ gimp_plug_in_proc_frame_pop (plug_in); } if (plug_in->main_proc_frame.main_loop && g_main_loop_is_running (plug_in->main_proc_frame.main_loop)) { #ifdef GIMP_UNSTABLE g_printerr ("plug-in '%s' aborted before sending its " "procedure return values\n", gimp_object_get_name (plug_in)); #endif g_main_loop_quit (plug_in->main_proc_frame.main_loop); } if (plug_in->ext_main_loop && g_main_loop_is_running (plug_in->ext_main_loop)) { #ifdef GIMP_UNSTABLE g_printerr ("extension '%s' aborted before sending its " "extension_ack message\n", gimp_object_get_name (plug_in)); #endif g_main_loop_quit (plug_in->ext_main_loop); } /* Unregister any temporary procedures. */ while (plug_in->temp_procedures) gimp_plug_in_remove_temp_proc (plug_in, plug_in->temp_procedures->data); gimp_plug_in_manager_remove_open_plug_in (plug_in->manager, plug_in); }