static void gimp_plug_in_handle_tile_get (GimpPlugIn *plug_in, GPTileReq *request) { GPTileData tile_data; GimpWireMessage msg; GimpDrawable *drawable; GeglBuffer *buffer; const Babl *format; GeglRectangle tile_rect; gint tile_size; drawable = (GimpDrawable *) gimp_item_get_by_ID (plug_in->manager->gimp, request->drawable_ID); if (! GIMP_IS_DRAWABLE (drawable)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Plug-In \"%s\"\n(%s)\n\n" "tried reading from invalid drawable %d (killing)", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file), request->drawable_ID); gimp_plug_in_close (plug_in, TRUE); return; } else if (gimp_item_is_removed (GIMP_ITEM (drawable))) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Plug-In \"%s\"\n(%s)\n\n" "tried reading from drawable %d which was removed " "from the image (killing)", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file), request->drawable_ID); gimp_plug_in_close (plug_in, TRUE); return; } if (request->shadow) { buffer = gimp_drawable_get_shadow_buffer (drawable); gimp_plug_in_cleanup_add_shadow (plug_in, drawable); } else { buffer = gimp_drawable_get_buffer (drawable); } if (! gimp_gegl_buffer_get_tile_rect (buffer, GIMP_PLUG_IN_TILE_WIDTH, GIMP_PLUG_IN_TILE_HEIGHT, request->tile_num, &tile_rect)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Plug-In \"%s\"\n(%s)\n\n" "requested invalid tile (killing)", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file)); gimp_plug_in_close (plug_in, TRUE); return; } format = gegl_buffer_get_format (buffer); if (! gimp_plug_in_precision_enabled (plug_in)) { format = gimp_babl_compat_u8_format (format); } tile_size = (babl_format_get_bytes_per_pixel (format) * tile_rect.width * tile_rect.height); tile_data.drawable_ID = request->drawable_ID; tile_data.tile_num = request->tile_num; tile_data.shadow = request->shadow; tile_data.bpp = babl_format_get_bytes_per_pixel (format); tile_data.width = tile_rect.width; tile_data.height = tile_rect.height; tile_data.use_shm = (plug_in->manager->shm != NULL); if (tile_data.use_shm) { gegl_buffer_get (buffer, &tile_rect, 1.0, format, gimp_plug_in_shm_get_addr (plug_in->manager->shm), GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); } else { tile_data.data = g_malloc (tile_size); gegl_buffer_get (buffer, &tile_rect, 1.0, format, tile_data.data, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); } if (! gp_tile_data_write (plug_in->my_write, &tile_data, plug_in)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "%s: ERROR", G_STRFUNC); gimp_plug_in_close (plug_in, TRUE); return; } if (! gimp_wire_read_msg (plug_in->my_read, &msg, plug_in)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "%s: ERROR", G_STRFUNC); gimp_plug_in_close (plug_in, TRUE); return; } if (msg.type != GP_TILE_ACK) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "expected tile ack and received: %d", msg.type); gimp_plug_in_close (plug_in, TRUE); return; } gimp_wire_destroy (&msg); }
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_filename_to_utf8 (plug_in->prog)); } g_object_unref (plug_in); return TRUE; }
static void gimp_plug_in_handle_tile_put (GimpPlugIn *plug_in, GPTileReq *request) { GPTileData tile_data; GPTileData *tile_info; GimpWireMessage msg; GimpDrawable *drawable; GeglBuffer *buffer; const Babl *format; GeglRectangle tile_rect; tile_data.drawable_ID = -1; tile_data.tile_num = 0; tile_data.shadow = 0; tile_data.bpp = 0; tile_data.width = 0; tile_data.height = 0; tile_data.use_shm = (plug_in->manager->shm != NULL); tile_data.data = NULL; if (! gp_tile_data_write (plug_in->my_write, &tile_data, plug_in)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "%s: ERROR", G_STRFUNC); gimp_plug_in_close (plug_in, TRUE); return; } if (! gimp_wire_read_msg (plug_in->my_read, &msg, plug_in)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "%s: ERROR", G_STRFUNC); gimp_plug_in_close (plug_in, TRUE); return; } if (msg.type != GP_TILE_DATA) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "expected tile data and received: %d", msg.type); gimp_plug_in_close (plug_in, TRUE); return; } tile_info = msg.data; drawable = (GimpDrawable *) gimp_item_get_by_ID (plug_in->manager->gimp, tile_info->drawable_ID); if (! GIMP_IS_DRAWABLE (drawable)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Plug-In \"%s\"\n(%s)\n\n" "tried writing to invalid drawable %d (killing)", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file), tile_info->drawable_ID); gimp_plug_in_close (plug_in, TRUE); return; } else if (gimp_item_is_removed (GIMP_ITEM (drawable))) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Plug-In \"%s\"\n(%s)\n\n" "tried writing to drawable %d which was removed " "from the image (killing)", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file), tile_info->drawable_ID); gimp_plug_in_close (plug_in, TRUE); return; } if (tile_info->shadow) { /* don't check whether the drawable is a group or locked here, * the plugin will get a proper error message when it tries to * merge the shadow tiles, which is much better than just * killing it. */ buffer = gimp_drawable_get_shadow_buffer (drawable); gimp_plug_in_cleanup_add_shadow (plug_in, drawable); } else { if (gimp_item_is_content_locked (GIMP_ITEM (drawable))) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Plug-In \"%s\"\n(%s)\n\n" "tried writing to a locked drawable %d (killing)", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file), tile_info->drawable_ID); gimp_plug_in_close (plug_in, TRUE); return; } else if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Plug-In \"%s\"\n(%s)\n\n" "tried writing to a group layer %d (killing)", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file), tile_info->drawable_ID); gimp_plug_in_close (plug_in, TRUE); return; } buffer = gimp_drawable_get_buffer (drawable); } if (! gimp_gegl_buffer_get_tile_rect (buffer, GIMP_PLUG_IN_TILE_WIDTH, GIMP_PLUG_IN_TILE_HEIGHT, tile_info->tile_num, &tile_rect)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "Plug-In \"%s\"\n(%s)\n\n" "requested invalid tile (killing)", gimp_object_get_name (plug_in), gimp_file_get_utf8_name (plug_in->file)); gimp_plug_in_close (plug_in, TRUE); return; } format = gegl_buffer_get_format (buffer); if (! gimp_plug_in_precision_enabled (plug_in)) { format = gimp_babl_compat_u8_format (format); } if (tile_data.use_shm) { gegl_buffer_set (buffer, &tile_rect, 0, format, gimp_plug_in_shm_get_addr (plug_in->manager->shm), GEGL_AUTO_ROWSTRIDE); } else { gegl_buffer_set (buffer, &tile_rect, 0, format, tile_info->data, GEGL_AUTO_ROWSTRIDE); } gimp_wire_destroy (&msg); if (! gp_tile_ack_write (plug_in->my_write, plug_in)) { gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR, "%s: ERROR", G_STRFUNC); gimp_plug_in_close (plug_in, TRUE); return; } }