Esempio n. 1
0
void
gimp_plug_in_manager_call_init (GimpPlugInManager *manager,
                                GimpContext       *context,
                                GimpPlugInDef     *plug_in_def)
{
  GimpPlugIn *plug_in;

  g_return_if_fail (GIMP_IS_PLUG_IN_MANAGER (manager));
  g_return_if_fail (GIMP_IS_PDB_CONTEXT (context));
  g_return_if_fail (GIMP_IS_PLUG_IN_DEF (plug_in_def));

  plug_in = gimp_plug_in_new (manager, context, NULL,
                              NULL, plug_in_def->file);

  if (plug_in)
    {
      plug_in->plug_in_def = plug_in_def;

      if (gimp_plug_in_open (plug_in, GIMP_PLUG_IN_CALL_INIT, TRUE))
        {
          while (plug_in->open)
            {
              GimpWireMessage msg;

              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);
                }
            }
        }

      g_object_unref (plug_in);
    }
}
Esempio n. 2
0
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_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 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;
    }
}