On Saturday 02 October 2004 17:27, Andraz Tori wrote: > So... Cinelerra now has this plugin that enables to edit SVG pictures > in sodipodi and then seamlessly use them in cinelerra as an overlay > (implemented by plugin). > > Now, since it seems that sodipodi is gone sniffing the dasies, i am > wondering is someone proficent enough in GTK coding to be willing to > port the patch from sodipodi to inkscape? > > basically it adds a GUI button 'e' when started with special command > line, uses a shift+cntrl+e keycombo for this button, and does the > shared memory passtrough of the rendered picture to cinelerra... > > anyone new who would like to get to the dark side of the pushing > cinelerra even further?
Better late than never, right? Here's the patch, ported to the latest SVN build of Inkscape. -Joe
diff -Pru inkscape-orig/src/Makefile_insert inkscape/src/Makefile_insert --- inkscape-orig/src/Makefile_insert 2006-05-27 11:40:53.000000000 -0400 +++ inkscape/src/Makefile_insert 2006-05-27 11:43:49.000000000 -0400 @@ -42,6 +42,7 @@ attributes.cpp attributes.h \ bad-uri-exception.h \ brokenimage.xpm \ + cinelerra.cpp cinelerra.h \ color-rgba.h \ color-profile.cpp color-profile.h \ color-profile-fns.h \ diff -Pru inkscape-orig/src/cinelerra.cpp inkscape/src/cinelerra.cpp --- inkscape-orig/src/cinelerra.cpp 1969-12-31 19:00:00.000000000 -0500 +++ inkscape/src/cinelerra.cpp 2006-05-27 11:45:37.000000000 -0400 @@ -0,0 +1,258 @@ +#define __CINELERRA_C__ + +/* All of the code added to Inkscape for integration with Cinelerra -- + * minus the interface stuff etc. that has to go into Inkscape's main + * code. All of it is tagged with "CINELERRA". */ + +#include <unistd.h> +#include <sys/file.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include "path-prefix.h" + +#include "inkscape.h" +#include "gc-core.h" +#include "sp-root.h" +#include "file.h" +#include "document.h" +#include "sp-object.h" +#include "unit-constants.h" +#include "xml/repr.h" +#include "color.h" +#include "svg/svg-color.h" +#include "svg/svg.h" +#include "cinelerra.h" +struct _Cinelerra Cinelerra; + +static gchar *sp_export_dpi = NULL; +static gchar *sp_export_area = NULL; +static gchar *sp_export_background = NULL; +static gboolean sp_export_use_hints = FALSE; +static gchar *sp_export_id = NULL; +static gboolean sp_export_area_drawing = FALSE; +static gboolean sp_export_id_only = FALSE; +static gboolean sp_export_area_canvas = FALSE; +static gboolean sp_export_area_snap = FALSE; +static gchar *sp_export_background_opacity = NULL; +static gchar *sp_export_height = NULL; +static gchar *sp_export_width = NULL; + + +void cin_export(GtkWidget *widget, GdkEvent *event, gpointer data) +{ + SPDocument *doc; + doc = SP_ACTIVE_DOCUMENT; + cin_do_export_raw(doc); + sp_file_save(NULL, NULL); +} + +void +cin_do_export_raw(SPDocument *doc) +{ + /* This entire section is the sp_do_export_png function found in + * main.cpp, which seems to be not for use globally. I made a few + * minor modifications to get rid of gcc warnings and extra + * pointers. */ + + gdouble dpi = 0.0; + + if (sp_export_use_hints && (!sp_export_id && !sp_export_area_drawing)) { + g_warning ("--export-use-hints can only be used with --export-id or --export-area-drawing; ignored."); + } + + GSList *items = NULL; + + NRRect area; + if (sp_export_id || sp_export_area_drawing) { + + SPObject *o = NULL; + SPObject *o_area = NULL; + if (sp_export_id && sp_export_area_drawing) { + o = doc->getObjectById(sp_export_id); + o_area = SP_DOCUMENT_ROOT (doc); + } else if (sp_export_id) { + o = doc->getObjectById(sp_export_id); + o_area = o; + } else if (sp_export_area_drawing) { + o = SP_DOCUMENT_ROOT (doc); + o_area = o; + } + + if (o) { + if (!SP_IS_ITEM (o)) { + g_warning("Object with id=\"%s\" is not a visible item. Nothing exported.", sp_export_id); + return; + } + + items = g_slist_prepend (items, SP_ITEM(o)); + + if (sp_export_id_only) { + g_print("Exporting only object with id=\"%s\"; all other objects hidden\n", sp_export_id); + } + + if (sp_export_use_hints) { + // retrieve export dpi hints + const gchar *dpi_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-xdpi"); // only xdpi, ydpi is always the same now + if (dpi_hint) { + if (sp_export_dpi || sp_export_width || sp_export_height) { + g_warning ("Using bitmap dimensions from the command line (--export-dpi, --export-width, or --export-height). DPI hint %s is ignored.", dpi_hint); + } else { + dpi = atof(dpi_hint); + } + } else { + g_warning ("Export DPI hint not found for the object."); + } + + } + + // write object bbox to area + sp_document_ensure_up_to_date (doc); + sp_item_invoke_bbox((SPItem *) o_area, &area, sp_item_i2r_affine((SPItem *) o_area), TRUE); + } else { + g_warning("Object with id=\"%s\" was not found in the document. Nothing exported.", sp_export_id); + return; + } + } + + if (sp_export_area) { + /* Try to parse area (given in SVG pixels) */ + if (!sscanf(sp_export_area, "%lg:%lg:%lg:%lg", &area.x0, &area.y0, &area.x1, &area.y1) == 4) { + g_warning("Cannot parse export area '%s'; use 'x0:y0:x1:y1'. Nothing exported.", sp_export_area); + return; + } + if ((area.x0 >= area.x1) || (area.y0 >= area.y1)) { + g_warning("Export area '%s' has negative width or height. Nothing exported.", sp_export_area); + return; + } + } else if (sp_export_area_canvas || !(sp_export_id || sp_export_area_drawing)) { + /* Export the whole canvas */ + sp_document_ensure_up_to_date (doc); + area.x0 = SP_ROOT(doc->root)->x.computed; + area.y0 = SP_ROOT(doc->root)->y.computed; + area.x1 = area.x0 + sp_document_width (doc); + area.y1 = area.y0 + sp_document_height (doc); + } + + if (sp_export_dpi && dpi == 0.0) { + dpi = atof(sp_export_dpi); + if ((dpi < 0.1) || (dpi > 10000.0)) { + g_warning("DPI value %s out of range [0.1 - 10000.0]. Nothing exported.", sp_export_dpi); + return; + } + g_print("DPI: %g\n", dpi); + } + + if (sp_export_area_snap) { + area.x0 = std::floor (area.x0); + area.y0 = std::floor (area.y0); + area.x1 = std::ceil (area.x1); + area.y1 = std::ceil (area.y1); + } + + // default dpi + if (dpi == 0.0) + dpi = PX_PER_IN; + + gint width = 0; + gint height = 0; + + if (Cinelerra.width) { + width = atoi(Cinelerra.width); + if ((width < 16) || (width > 65536)) { + g_warning("Export width %d out of range (16 - 65536). Nothing exported.", width); + return; + } + dpi = (gdouble) width * PX_PER_IN / (area.x1 - area.x0); + } + + if (Cinelerra.height) { + height = atoi(Cinelerra.height); + if ((height < 16) || (height > 65536)) { + g_warning("Export height %d out of range (16 - 65536). Nothing exported.", width); + return; + } + dpi = (gdouble) height * PX_PER_IN / (area.y1 - area.y0); + } + + if (!Cinelerra.width) { + width = (gint) ((area.x1 - area.x0) * dpi / PX_PER_IN + 0.5); + } + + if (!Cinelerra.height) { + height = (gint) ((area.y1 - area.y0) * dpi / PX_PER_IN + 0.5); + } + + guint32 bgcolor = 0x00000000; + if (sp_export_background) { + // override the page color + bgcolor = sp_svg_read_color(sp_export_background, 0xffffff00); + bgcolor |= 0xff; // default is no opacity + } else { + // read from namedview + Inkscape::XML::Node *nv = sp_repr_lookup_name (doc->rroot, "sodipodi:namedview"); + if (nv && nv->attribute("pagecolor")) + bgcolor = sp_svg_read_color(nv->attribute("pagecolor"), 0xffffff00); + if (nv && nv->attribute("inkscape:pageopacity")) + bgcolor |= SP_COLOR_F_TO_U(sp_repr_get_double_attribute (nv, "inkscape:pageopacity", 1.0)); + } + + if (sp_export_background_opacity) { + // override opacity + gfloat value; + if (sp_svg_number_read_f (sp_export_background_opacity, &value)) { + if (value > 1.0) { + value = CLAMP (value, 1.0f, 255.0f); + bgcolor &= (guint32) 0xffffff00; + bgcolor |= (guint32) floor(value); + } else { + value = CLAMP (value, 0.0f, 1.0f); + bgcolor &= (guint32) 0xffffff00; + bgcolor |= SP_COLOR_F_TO_U(value); + } + } + } + + g_print("Background RRGGBBAA: %08x\n", bgcolor); + + g_print("Area %g:%g:%g:%g exported to %d x %d pixels (%g dpi)\n", area.x0, area.y0, area.x1, area.y1, width, height, dpi); + + if ((width >= 1) && (height >= 1) && (width < 65536) && (height < 65536)) { + // We lock the file so there is just one reader/writer at a time + gchar *filename_fifo; + int fh_raw; + int fh_fifo; + struct fifo_struct fifo_buf; + +// printf("Inkscape locking %s! \n", filename_lock); + fh_raw = open (Cinelerra.exportfile, O_CREAT|O_RDWR, S_IRUSR | S_IWUSR); + int res = lockf(fh_raw, F_LOCK, 0); // Blocking call - will wait for other inkscape or cinelerra +// printf("Inkscape: filehandle: %i, res: %i, errno: %i\n", fh_raw, res, errno); + sp_export_raw_file (doc, fh_raw, + area.x0, area.y0, area.x1, + area.y1, width, height, bgcolor); + lockf(fh_raw, F_ULOCK, 0); + close(fh_raw); + printf("exporting finished\n"); + filename_fifo = g_strconcat(Cinelerra.exportfile, ".fifo"); + fh_fifo = open(filename_fifo, O_RDWR); +// printf("Inkscape fifo %s! \n", filename_fifo); + // printf("Inkscape: filehandle: %i, res: %i, errno: %i\n", fh_fifo, res, errno); + + fifo_buf.pid = getpid(); + fifo_buf.action = 1; // update from client + write(fh_fifo, &fifo_buf, sizeof(fifo_buf)); + close(fh_fifo); + g_free(filename_fifo); +// printf("Inkscape unlocking!\n"); + } else { + g_warning("Calculated bitmap dimensions %d %d are out of range (1 - 65535). Nothing exported.", width, height); + } + + g_slist_free (items); +} + diff -Pru inkscape-orig/src/cinelerra.h inkscape/src/cinelerra.h --- inkscape-orig/src/cinelerra.h 1969-12-31 19:00:00.000000000 -0500 +++ inkscape/src/cinelerra.h 2006-05-27 11:45:38.000000000 -0400 @@ -0,0 +1,34 @@ +#ifndef SEEN_CINELERRA_H +#define SEEN_CINELERRA_H + +struct _Cinelerra { + const gchar *exportfile; + const gchar *svgfile; + const gchar *width; + const gchar *height; +}; + +struct fifo_struct { + int pid; + int action; // 1 = update from client, 2 = client closes +}; + +struct raw_struct { + char rawc[5]; // Null terminated "RAWC" string + int32_t struct_version; // currently 1 (bumped at each destructive change) + int32_t struct_size; // size of this struct in bytes + int32_t width; // logical width of image + int32_t height; + int32_t pitch; // physical width of image in memory + int32_t color_model; // as BC_ constant, currently only BC_RGBA8888 is supported + int64_t time_of_creation; // in milliseconds - calculated as (tv_sec * 1000 + tv_usec / 1000); + // we can't trust date on the file, due to different reasons +}; + +#define BC_RGB888 9 +#define BC_RGBA8888 10 + +void cin_export(GtkWidget *widget, GdkEvent *event, gpointer data); +void cin_do_export_raw(SPDocument *doc); + +#endif diff -Pru inkscape-orig/src/file.cpp inkscape/src/file.cpp --- inkscape-orig/src/file.cpp 2006-05-27 11:40:53.000000000 -0400 +++ inkscape/src/file.cpp 2006-05-27 11:50:39.000000000 -0400 @@ -61,6 +61,17 @@ #include "inkscape.h" #include "uri.h" +/* CINELERRA */ +#include "cinelerra.h" +#include <fcntl.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/time.h> +#include "macros.h" +#include "forward.h" + #ifdef WITH_INKBOARD #include "jabber_whiteboard/session-manager.h" #endif @@ -1230,6 +1241,117 @@ } +/* CINELERRA */ + + +void +sp_export_raw_file (SPDocument *doc, int fh_raw, + double x0, double y0, double x1, double y1, + unsigned int width, unsigned int height, + unsigned long bgcolor) +{ + NRMatrix affine; + gdouble t; + NRArena *arena; + struct SPEBP ebp; + unsigned int dkey; + + g_return_if_fail (doc != NULL); + //g_return_if_fail (SP_IS_DOCUMENT (doc)); + g_return_if_fail (fh_raw != -1); + g_return_if_fail (width >= 16); + g_return_if_fail (height >= 16); + + sp_document_ensure_up_to_date (doc); + + /* Go to document coordinates */ + t = y0; + y0 = sp_document_height (doc) - y1; + y1 = sp_document_height (doc) - t; + + /* + * 1) a[0] * x0 + a[2] * y1 + a[4] = 0.0 + * 2) a[1] * x0 + a[3] * y1 + a[5] = 0.0 + * 3) a[0] * x1 + a[2] * y1 + a[4] = width + * 4) a[1] * x0 + a[3] * y0 + a[5] = height + * 5) a[1] = 0.0; + * 6) a[2] = 0.0; + * + * (1,3) a[0] * x1 - a[0] * x0 = width + * a[0] = width / (x1 - x0) + * (2,4) a[3] * y0 - a[3] * y1 = height + * a[3] = height / (y0 - y1) + * (1) a[4] = -a[0] * x0 + * (2) a[5] = -a[3] * y1 + */ + + affine.c[0] = width / ((x1 - x0) * 1.25); + affine.c[1] = 0.0; + affine.c[2] = 0.0; + affine.c[3] = height / ((y1 - y0) * 1.25); + affine.c[4] = -affine.c[0] * x0 * 1.25; + affine.c[5] = -affine.c[3] * y0 * 1.25; + + SP_PRINT_MATRIX ("SVG2PNG", &affine); + + ebp.width = width; + ebp.height = height; + ebp.r = NR_RGBA32_R (bgcolor); + ebp.g = NR_RGBA32_G (bgcolor); + ebp.b = NR_RGBA32_B (bgcolor); + ebp.a = NR_RGBA32_A (bgcolor); + + /* Create new arena */ + arena = (NRArena *) nr_object_new (NR_TYPE_ARENA); + dkey = sp_item_display_key_new (1); + /* Create ArenaItem and set transform */ + ebp.root = sp_item_invoke_show (SP_ITEM (sp_document_root (doc)), arena, dkey, SP_ITEM_SHOW_DISPLAY); + nr_arena_item_set_transform (ebp.root, &affine); + { + int len_raw; + void *buffer; + struct raw_struct *raw_data; + struct timeval current_time; + + const unsigned char ** rows = nr_new (const unsigned char *, height); + ebp.sheight = height; + len_raw = 4 * height * width + sizeof(struct raw_struct); + ftruncate(fh_raw, len_raw); + + buffer = mmap(NULL, len_raw, PROT_WRITE | PROT_READ, MAP_SHARED, fh_raw, 0); + raw_data = (struct raw_struct *) buffer; + strcpy(raw_data->rawc, "RAWC"); + raw_data->struct_version = 1; + raw_data->struct_size = sizeof(struct raw_struct); + raw_data->width = width; + raw_data->height = height; + raw_data->pitch = width; // width == pitch currently + raw_data->color_model = BC_RGBA8888; + +// we use a trick of writing directly to shared memory +// ebp.px = nr_new (unsigned char, 4 * height * width); + ebp.px = (guchar *)((unsigned int)buffer + sizeof(struct raw_struct)); + sp_export_get_rows(rows, 0, height, &ebp); + + // update time_of_creation after export + gettimeofday(¤t_time, 0); + raw_data->time_of_creation = (int64_t)current_time.tv_sec * 1000 + (int64_t)current_time.tv_usec / 1000; + + + munmap (buffer, len_raw); + nr_free(rows); +// nr_free (ebp.px); + + } + + + /* Free Arena and ArenaItem */ + sp_item_invoke_hide (SP_ITEM (sp_document_root (doc)), dkey); + nr_arena_item_unref (ebp.root); + nr_object_unref ((NRObject *) arena); +} + + void Inkscape::IO::fixupHrefs( SPDocument *doc, const gchar *base, gboolean spns ) { //g_message("Inkscape::IO::fixupHrefs( , [%s], )", base ); diff -Pru inkscape-orig/src/file.h inkscape/src/file.h --- inkscape-orig/src/file.h 2006-05-27 11:40:53.000000000 -0400 +++ inkscape/src/file.h 2006-05-27 13:42:37.000000000 -0400 @@ -166,6 +166,11 @@ */ void sp_file_vacuum (); +/* CINELERRA */ +void sp_export_raw_file (SPDocument *doc, int fh_raw, + double x0, double y0, double x1, double y1, + unsigned int width, unsigned int height, + unsigned long bgcolor); namespace Inkscape { namespace IO { diff -Pru inkscape-orig/src/main.cpp inkscape/src/main.cpp --- inkscape-orig/src/main.cpp 2006-05-27 11:40:53.000000000 -0400 +++ inkscape/src/main.cpp 2006-05-27 11:43:49.000000000 -0400 @@ -102,6 +102,8 @@ #include <glibmm/i18n.h> #include <gtkmm/main.h> +#include "cinelerra.h" + #ifndef HAVE_BIND_TEXTDOMAIN_CODESET #define bind_textdomain_codeset(p,c) #endif @@ -142,9 +144,13 @@ SP_ARG_VERSION, SP_ARG_NEW_GUI, SP_ARG_VACUUM_DEFS, - SP_ARG_LAST + SP_ARG_LAST, + CIN_ARG_EXPORT_FILE // CINELERRA export file }; +/* CINELERRA */ +extern struct _Cinelerra Cinelerra; + int sp_main_gui(int argc, char const **argv); int sp_main_console(int argc, char const **argv); static void sp_do_export_png(SPDocument *doc); @@ -355,7 +361,9 @@ POPT_ARG_NONE, &sp_vacuum_defs, SP_ARG_VACUUM_DEFS, N_("Remove unused definitions from the defs section(s) of the document"), NULL}, - + /* CINELERRA cmd line addition */ + {"cinelerra-export-file", 0, POPT_ARG_STRING, &Cinelerra.exportfile, + CIN_ARG_EXPORT_FILE, N_("Cinelerra export file"), NULL}, POPT_AUTOHELP POPT_TABLEEND }; @@ -452,7 +460,10 @@ /* main_console handles any exports -- not the gui */ use_gui = FALSE; break; - } else if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--with-gui")) { + } else if (!strcmp(argv[i], "-g") || + !strcmp(argv[i], "--with-gui") || + // CINELERRA uses gui + !strncmp(argv[i], "--cinelerra-export-file", 23)) { use_gui = TRUE; break; } else if (!strcmp(argv[i], "-G") || !strcmp(argv[i], "--new-gui")) { @@ -698,6 +709,9 @@ if (sp_export_png || sp_export_id || sp_export_area_drawing) { sp_do_export_png(doc); } + if (Cinelerra.exportfile) { + cin_do_export_raw(doc); + } if (sp_export_svg) { Inkscape::XML::Document *rdoc; Inkscape::XML::Node *repr; @@ -1303,10 +1317,11 @@ GSList *fl = NULL; gint a; + gchar const *fn; while ((a = poptGetNextOpt(ctx)) >= 0) { switch (a) { case SP_ARG_FILE: { - gchar const *fn = poptGetOptArg(ctx); + fn = poptGetOptArg(ctx); if (fn != NULL) { fl = g_slist_append(fl, g_strdup(fn)); } @@ -1322,6 +1337,30 @@ exit(0); break; } +/* CINELERRA addition for args */ + case CIN_ARG_EXPORT_FILE: + fn = poptGetOptArg (ctx); + if(fn != NULL && strlen(fn) > 0) { + gchar *tmp; + tmp = (gchar *) g_malloc(strlen(fn) + 5); + Cinelerra.exportfile = fn; + sprintf(tmp, "%s.svg", fn); + Cinelerra.svgfile = tmp; + } else { + g_error("--cinelerra-export-file found, but no filename!"); + } + break; + case SP_ARG_EXPORT_WIDTH: + fn = poptGetOptArg(ctx); + if(fn != NULL) + Cinelerra.width = fn; + break; + case SP_ARG_EXPORT_HEIGHT: + fn = poptGetOptArg(ctx); + if(fn != NULL) + Cinelerra.height = fn; + break; +/* END CINELERRA addition for args */ default: { break; } diff -Pru inkscape-orig/src/verbs.cpp inkscape/src/verbs.cpp --- inkscape-orig/src/verbs.cpp 2006-05-27 11:40:53.000000000 -0400 +++ inkscape/src/verbs.cpp 2006-05-27 11:43:49.000000000 -0400 @@ -78,7 +78,9 @@ #include "sp-flowtext.h" #include "layer-fns.h" #include "node-context.h" - +/* CINELERRA */ +#include "cinelerra.h" +extern struct _Cinelerra Cinelerra; /** * \brief Return the name without underscores and ellipsis, for use in dialog @@ -352,6 +354,24 @@ { } }; //TextVerb : public Verb +/* CINELERRA */ +class CinelerraVerb : public Verb { +private: + static void perform(SPAction *action, void *mydata, void *otherdata); + static SPActionEventVector vector; +protected: + virtual SPAction *make_action(Inkscape::UI::View::View *view); +public: + /** \brief Use the Verb initializer with the same parameters. */ + CinelerraVerb(unsigned int const code, + gchar const *id, + gchar const *name, + gchar const *tip, + gchar const *image) : + Verb(code, id, name, tip, image) + { } +}; /* CinelerraVerb class */ + Verb::VerbTable Verb::_verbs; Verb::VerbIDTable Verb::_verb_ids; @@ -539,6 +559,14 @@ return make_action_helper(view, &vector); } +/* CINELERRA */ +SPAction * +CinelerraVerb::make_action(Inkscape::UI::View::View *view) +{ + return make_action_helper(view, &vector); +} + + /** \brief A quick little convience function to make building actions a little bit easier. \param view Which view the action should be created for. @@ -1756,6 +1784,18 @@ } } // end of sp_verb_action_tutorial_perform() +/* CINELERRA */ +void +CinelerraVerb::perform(SPAction *action, void *data, void *pdata) +{ + switch((int) data) { + case SP_VERB_CINELERRA_EXPORT: + cin_export(NULL, NULL, NULL); + break; + default: + break; + } +} /** * Action vector to define functions called if a staticly defined file verb @@ -1835,6 +1875,10 @@ {{NULL},TextVerb::perform, NULL, NULL, NULL}; +/* CINELERRA */ +SPActionEventVector CinelerraVerb::vector = + {{NULL},CinelerraVerb::perform, NULL, NULL, NULL}; + /* *********** Effect Last ********** */ /** \brief A class to represent the last effect issued */ @@ -2411,6 +2455,9 @@ N_("Fit the canvas to the drawing"), NULL), new FitCanvasVerb(SP_VERB_FIT_CANVAS_TO_SELECTION_OR_DRAWING, "FitCanvasToSelectionOrDrawing", N_("Fit Canvas to Selection or Drawing"), N_("Fit the canvas to the current selection or the drawing if there is no selection"), NULL), + /* CINELERRA */ + new CinelerraVerb(SP_VERB_CINELERRA_EXPORT, "Cinelerra Export", + N_("Cinelerra Export"), N_("Cinelerra Export"), NULL), /* Footer */ new Verb(SP_VERB_LAST, " '\"invalid id", NULL, NULL, NULL) }; diff -Pru inkscape-orig/src/verbs.h inkscape/src/verbs.h --- inkscape-orig/src/verbs.h 2006-05-27 11:40:53.000000000 -0400 +++ inkscape/src/verbs.h 2006-05-27 11:43:49.000000000 -0400 @@ -229,6 +229,8 @@ SP_VERB_FIT_CANVAS_TO_SELECTION, SP_VERB_FIT_CANVAS_TO_DRAWING, SP_VERB_FIT_CANVAS_TO_SELECTION_OR_DRAWING, + /* CINELERRA */ + SP_VERB_CINELERRA_EXPORT, /* Footer */ SP_VERB_LAST }; diff -Pru inkscape-orig/src/widgets/desktop-widget.cpp inkscape/src/widgets/desktop-widget.cpp --- inkscape-orig/src/widgets/desktop-widget.cpp 2006-05-27 11:40:53.000000000 -0400 +++ inkscape/src/widgets/desktop-widget.cpp 2006-05-27 11:43:49.000000000 -0400 @@ -47,6 +47,9 @@ #include "sp-item.h" #include "dialogs/swatches.h" #include "conn-avoid-ref.h" +/* CINELERRA */ +#include "cinelerra.h" +extern struct _Cinelerra Cinelerra; #ifdef WITH_INKBOARD #endif @@ -247,6 +250,16 @@ gtk_box_pack_start (GTK_BOX (dtw->vscrollbar_box), dtw->vscrollbar, TRUE, TRUE, 0); gtk_table_attach (GTK_TABLE (tbl), dtw->vscrollbar_box, 2, 3, 0, 2, (GtkAttachOptions)(GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0); + /* CINELERRA export button */ + if (Cinelerra.exportfile != NULL) + { + dtw->exbtn = gtk_button_new_with_label("E"); + gtk_table_attach(GTK_TABLE(tbl), dtw->exbtn, 2, 3, 2, 3, GTK_FILL, + GTK_FILL, 0, 0); + g_signal_connect (G_OBJECT (dtw->exbtn), "button_release_event", + G_CALLBACK (cin_export), dtw); + } + /* Canvas */ dtw->canvas = SP_CANVAS (sp_canvas_new_aa ()); GTK_WIDGET_SET_FLAGS (GTK_WIDGET (dtw->canvas), GTK_CAN_FOCUS); diff -Pru inkscape-orig/src/widgets/desktop-widget.h inkscape/src/widgets/desktop-widget.h --- inkscape-orig/src/widgets/desktop-widget.h 2006-05-27 11:40:53.000000000 -0400 +++ inkscape/src/widgets/desktop-widget.h 2006-05-27 11:43:49.000000000 -0400 @@ -67,6 +67,9 @@ GtkWidget *menubar, *statusbar; GtkWidget *panels; + + /* CINELERRA export button */ + GtkWidget *exbtn; GtkWidget *hscrollbar, *vscrollbar, *vscrollbar_box;