Code

Added gnome-vfs patch by Ed Catmur so we can save/open/export to non-local
[inkscape.git] / src / main.cpp
1 #define __MAIN_C__
3 /** \file
4  * Inkscape - an ambitious vector drawing program
5  *
6  * Authors:
7  *   Lauris Kaplinski <lauris@kaplinski.com>
8  *   Frank Felfe <innerspace@iname.com>
9  *   Davide Puricelli <evo@debian.org>
10  *   Mitsuru Oka <oka326@parkcity.ne.jp>
11  *   Masatake YAMATO  <jet@gyve.org>
12  *   F.J.Franklin <F.J.Franklin@sheffield.ac.uk>
13  *   Michael Meeks <michael@helixcode.com>
14  *   Chema Celorio <chema@celorio.com>
15  *   Pawel Palucha
16  *   Bryce Harrington <bryce@bryceharrington.com>
17  * ... and various people who have worked with various projects
18  *
19  * Copyright (C) 1999-2004 authors
20  * Copyright (C) 2001-2002 Ximian, Inc.
21  *
22  * Released under GNU GPL, read the file 'COPYING' for more information
23  */
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29 #include "path-prefix.h"
31 #include <gtk/gtkmessagedialog.h>
33 #ifdef HAVE_IEEEFP_H
34 #include <ieeefp.h>
35 #endif
36 #include <string.h>
37 #include <locale.h>
39 #include <popt.h>
40 #ifndef POPT_TABLEEND
41 #define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL }
42 #endif /* Not def: POPT_TABLEEND */
44 #include <libxml/tree.h>
45 #include <glib-object.h>
46 #include <gtk/gtkmain.h>
47 #include <gtk/gtksignal.h>
48 #include <gtk/gtkwindow.h>
49 #include <gtk/gtkbox.h>
51 #include "gc-core.h"
53 #include "macros.h"
54 #include "file.h"
55 #include "document.h"
56 #include "sp-object.h"
57 #include "interface.h"
58 #include "print.h"
59 #include "slideshow.h"
60 #include "color.h"
61 #include "sp-item.h"
62 #include "sp-root.h"
63 #include "unit-constants.h"
65 #include "svg/svg.h"
66 #include "svg/svg-color.h"
67 #include "svg/stringstream.h"
69 #include "inkscape-private.h"
70 #include "inkscape-stock.h"
71 #include "inkscape_version.h"
73 #include "sp-namedview.h"
74 #include "sp-guide.h"
75 #include "sp-object-repr.h"
76 #include "xml/repr.h"
78 #include "io/sys.h"
80 #include "debug/logger.h"
82 #include "helper/png-write.h"
84 #include <extension/extension.h>
85 #include <extension/system.h>
86 #include <extension/db.h>
87 #include <extension/output.h>
89 #ifdef WIN32
90 //#define REPLACEARGS_ANSI
91 //#define REPLACEARGS_DEBUG
93 #include "registrytool.h"
95 #include "extension/internal/win32.h"
96 using Inkscape::Extension::Internal::PrintWin32;
98 #endif // WIN32
100 #include "extension/init.h"
102 #include <glibmm/i18n.h>
103 #include <gtkmm/main.h>
105 #ifndef HAVE_BIND_TEXTDOMAIN_CODESET
106 #define bind_textdomain_codeset(p,c)
107 #endif
109 #include "application/application.h"
111 enum {
112     SP_ARG_NONE,
113     SP_ARG_NOGUI,
114     SP_ARG_GUI,
115     SP_ARG_FILE,
116     SP_ARG_PRINT,
117     SP_ARG_EXPORT_PNG,
118     SP_ARG_EXPORT_DPI,
119     SP_ARG_EXPORT_AREA,
120     SP_ARG_EXPORT_AREA_DRAWING,
121     SP_ARG_EXPORT_AREA_CANVAS,
122     SP_ARG_EXPORT_AREA_SNAP,
123     SP_ARG_EXPORT_WIDTH,
124     SP_ARG_EXPORT_HEIGHT,
125     SP_ARG_EXPORT_ID,
126     SP_ARG_EXPORT_ID_ONLY,
127     SP_ARG_EXPORT_USE_HINTS,
128     SP_ARG_EXPORT_BACKGROUND,
129     SP_ARG_EXPORT_BACKGROUND_OPACITY,
130     SP_ARG_EXPORT_SVG,
131     SP_ARG_EXPORT_PS,
132     SP_ARG_EXPORT_EPS,
133     SP_ARG_EXPORT_PDF,
134     SP_ARG_EXPORT_TEXT_TO_PATH,
135     SP_ARG_EXPORT_FONT,
136     SP_ARG_EXPORT_BBOX_PAGE,
137     SP_ARG_EXTENSIONDIR,
138     SP_ARG_FIT_PAGE_TO_DRAWING,
139     SP_ARG_SLIDESHOW,
140     SP_ARG_QUERY_X,
141     SP_ARG_QUERY_Y,
142     SP_ARG_QUERY_WIDTH,
143     SP_ARG_QUERY_HEIGHT,
144     SP_ARG_QUERY_ID,
145     SP_ARG_VERSION,
146     SP_ARG_VACUUM_DEFS,
147     SP_ARG_LAST
148 };
150 int sp_main_gui(int argc, char const **argv);
151 int sp_main_console(int argc, char const **argv);
152 static void sp_do_export_png(SPDocument *doc);
153 static void do_export_ps(SPDocument* doc, gchar const* uri, char const *mime);
154 static void do_export_pdf(SPDocument* doc, gchar const* uri, char const *mime);
155 static void do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gchar *id);
158 static gchar *sp_global_printer = NULL;
159 static gboolean sp_global_slideshow = FALSE;
160 static gchar *sp_export_png = NULL;
161 static gchar *sp_export_dpi = NULL;
162 static gchar *sp_export_area = NULL;
163 static gboolean sp_export_area_drawing = FALSE;
164 static gboolean sp_export_area_canvas = FALSE;
165 static gchar *sp_export_width = NULL;
166 static gchar *sp_export_height = NULL;
167 static gchar *sp_export_id = NULL;
168 static gchar *sp_export_background = NULL;
169 static gchar *sp_export_background_opacity = NULL;
170 static gboolean sp_export_area_snap = FALSE;
171 static gboolean sp_export_use_hints = FALSE;
172 static gboolean sp_export_id_only = FALSE;
173 static gchar *sp_export_svg = NULL;
174 static gchar *sp_export_ps = NULL;
175 static gchar *sp_export_eps = NULL;
176 static gchar *sp_export_pdf = NULL;
177 static gboolean sp_export_text_to_path = FALSE;
178 static gboolean sp_export_font = FALSE;
179 static gboolean sp_export_bbox_page = FALSE;
180 static gboolean sp_query_x = FALSE;
181 static gboolean sp_query_y = FALSE;
182 static gboolean sp_query_width = FALSE;
183 static gboolean sp_query_height = FALSE;
184 static gchar *sp_query_id = NULL;
185 static int sp_new_gui = FALSE;
186 static gboolean sp_vacuum_defs = FALSE;
188 static gchar *sp_export_png_utf8 = NULL;
189 static gchar *sp_export_svg_utf8 = NULL;
190 static gchar *sp_global_printer_utf8 = NULL;
192 #ifdef WIN32
193 static bool replaceArgs( int& argc, char**& argv );
194 #endif
195 static GSList *sp_process_args(poptContext ctx);
196 struct poptOption options[] = {
197     {"version", 'V',
198      POPT_ARG_NONE, NULL, SP_ARG_VERSION,
199      N_("Print the Inkscape version number"),
200      NULL},
202     {"without-gui", 'z',
203      POPT_ARG_NONE, NULL, SP_ARG_NOGUI,
204      N_("Do not use X server (only process files from console)"),
205      NULL},
207     {"with-gui", 'g',
208      POPT_ARG_NONE, NULL, SP_ARG_GUI,
209      N_("Try to use X server (even if $DISPLAY is not set)"),
210      NULL},
212     {"file", 'f',
213      POPT_ARG_STRING, NULL, SP_ARG_FILE,
214      N_("Open specified document(s) (option string may be excluded)"),
215      N_("FILENAME")},
217     {"print", 'p',
218      POPT_ARG_STRING, &sp_global_printer, SP_ARG_PRINT,
219      N_("Print document(s) to specified output file (use '| program' for pipe)"),
220      N_("FILENAME")},
222     {"export-png", 'e',
223      POPT_ARG_STRING, &sp_export_png, SP_ARG_EXPORT_PNG,
224      N_("Export document to a PNG file"),
225      N_("FILENAME")},
227     {"export-dpi", 'd',
228      POPT_ARG_STRING, &sp_export_dpi, SP_ARG_EXPORT_DPI,
229      N_("The resolution used for exporting SVG into bitmap (default 90)"),
230      N_("DPI")},
232     {"export-area", 'a',
233      POPT_ARG_STRING, &sp_export_area, SP_ARG_EXPORT_AREA,
234      N_("Exported area in SVG user units (default is the canvas; 0,0 is lower-left corner)"),
235      N_("x0:y0:x1:y1")},
237     {"export-area-drawing", 'D',
238      POPT_ARG_NONE, &sp_export_area_drawing, SP_ARG_EXPORT_AREA_DRAWING,
239      N_("Exported area is the entire drawing (not canvas)"),
240      NULL},
242     {"export-area-canvas", 'C',
243      POPT_ARG_NONE, &sp_export_area_canvas, SP_ARG_EXPORT_AREA_CANVAS,
244      N_("Exported area is the entire canvas"),
245      NULL},
247     {"export-area-snap", 0,
248      POPT_ARG_NONE, &sp_export_area_snap, SP_ARG_EXPORT_AREA_SNAP,
249      N_("Snap the bitmap export area outwards to the nearest integer values (in SVG user units)"),
250      NULL},
252     {"export-width", 'w',
253      POPT_ARG_STRING, &sp_export_width, SP_ARG_EXPORT_WIDTH,
254      N_("The width of exported bitmap in pixels (overrides export-dpi)"),
255      N_("WIDTH")},
257     {"export-height", 'h',
258      POPT_ARG_STRING, &sp_export_height, SP_ARG_EXPORT_HEIGHT,
259      N_("The height of exported bitmap in pixels (overrides export-dpi)"),
260      N_("HEIGHT")},
262     {"export-id", 'i',
263      POPT_ARG_STRING, &sp_export_id, SP_ARG_EXPORT_ID,
264      N_("The ID of the object to export"),
265      N_("ID")},
267     {"export-id-only", 'j',
268      POPT_ARG_NONE, &sp_export_id_only, SP_ARG_EXPORT_ID_ONLY,
269      // TRANSLATORS: this means: "Only export the object whose id is given in --export-id".
270      //  See "man inkscape" for details.
271      N_("Export just the object with export-id, hide all others (only with export-id)"),
272      NULL},
274     {"export-use-hints", 't',
275      POPT_ARG_NONE, &sp_export_use_hints, SP_ARG_EXPORT_USE_HINTS,
276      N_("Use stored filename and DPI hints when exporting (only with export-id)"),
277      NULL},
279     {"export-background", 'b',
280      POPT_ARG_STRING, &sp_export_background, SP_ARG_EXPORT_BACKGROUND,
281      N_("Background color of exported bitmap (any SVG-supported color string)"),
282      N_("COLOR")},
284     {"export-background-opacity", 'y',
285      POPT_ARG_STRING, &sp_export_background_opacity, SP_ARG_EXPORT_BACKGROUND_OPACITY,
286      N_("Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)"),
287      N_("VALUE")},
289     {"export-plain-svg", 'l',
290      POPT_ARG_STRING, &sp_export_svg, SP_ARG_EXPORT_SVG,
291      N_("Export document to plain SVG file (no sodipodi or inkscape namespaces)"),
292      N_("FILENAME")},
294     {"export-ps", 'P',
295      POPT_ARG_STRING, &sp_export_ps, SP_ARG_EXPORT_PS,
296      N_("Export document to a PS file"),
297      N_("FILENAME")},
299     {"export-eps", 'E',
300      POPT_ARG_STRING, &sp_export_eps, SP_ARG_EXPORT_EPS,
301      N_("Export document to an EPS file"),
302      N_("FILENAME")},
304     {"export-pdf", 'A',
305      POPT_ARG_STRING, &sp_export_pdf, SP_ARG_EXPORT_PDF,
306      N_("Export document to a PDF file"),
307      N_("FILENAME")},
309     {"export-text-to-path", 'T',
310      POPT_ARG_NONE, &sp_export_text_to_path, SP_ARG_EXPORT_TEXT_TO_PATH,
311      N_("Convert text object to paths on export (EPS)"),
312      NULL},
314     {"export-embed-fonts", 'F',
315      POPT_ARG_NONE, &sp_export_font, SP_ARG_EXPORT_FONT,
316      N_("Embed fonts on export (Type 1 only) (EPS)"),
317      NULL},
319     {"export-bbox-page", 'B',
320      POPT_ARG_NONE, &sp_export_bbox_page, SP_ARG_EXPORT_BBOX_PAGE,
321      N_("Export files with the bounding box set to the page size (EPS)"),
322      NULL},
324     {"fit-page-to-drawing", 'S',
325      POPT_ARG_NONE, &sp_export_bbox_page, SP_ARG_FIT_PAGE_TO_DRAWING,
326      N_("Fits page to drawing and saves changes in place"),
327      NULL},
329     {"query-x", 'X',
330      POPT_ARG_NONE, &sp_query_x, SP_ARG_QUERY_X,
331      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
332      N_("Query the X coordinate of the drawing or, if specified, of the object with --query-id"),
333      NULL},
335     {"query-y", 'Y',
336      POPT_ARG_NONE, &sp_query_y, SP_ARG_QUERY_Y,
337      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
338      N_("Query the Y coordinate of the drawing or, if specified, of the object with --query-id"),
339      NULL},
341     {"query-width", 'W',
342      POPT_ARG_NONE, &sp_query_width, SP_ARG_QUERY_WIDTH,
343      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
344      N_("Query the width of the drawing or, if specified, of the object with --query-id"),
345      NULL},
347     {"query-height", 'H',
348      POPT_ARG_NONE, &sp_query_height, SP_ARG_QUERY_HEIGHT,
349      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
350      N_("Query the height of the drawing or, if specified, of the object with --query-id"),
351      NULL},
353     {"query-id", 'I',
354      POPT_ARG_STRING, &sp_query_id, SP_ARG_QUERY_ID,
355      N_("The ID of the object whose dimensions are queried"),
356      N_("ID")},
358     {"extension-directory", 'x',
359      POPT_ARG_NONE, NULL, SP_ARG_EXTENSIONDIR,
360      // TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory
361      N_("Print out the extension directory and exit"),
362      NULL},
364     {"slideshow", 's',
365      POPT_ARG_NONE, &sp_global_slideshow, SP_ARG_SLIDESHOW,
366      N_("Show given files one-by-one, switch to next on any key/mouse event"),
367      NULL},
369     {"vacuum-defs", 0,
370      POPT_ARG_NONE, &sp_vacuum_defs, SP_ARG_VACUUM_DEFS,
371      N_("Remove unused definitions from the defs section(s) of the document"),
372      NULL},
374     POPT_AUTOHELP POPT_TABLEEND
375 };
377 static bool needToRecodeParams = true;
378 gchar* blankParam = "";
380 int
381 main(int argc, char **argv)
383 #ifdef HAVE_FPSETMASK
384     /* This is inherited from Sodipodi code, where it was in #ifdef __FreeBSD__.  It's probably
385        safe to remove: the default mask is already 0 in C99, and in current FreeBSD according to
386        the fenv man page on www.freebsd.org, and in glibc according to (libc)FP Exceptions. */
387     fpsetmask(fpgetmask() & ~(FP_X_DZ | FP_X_INV));
388 #endif
390 #ifdef ENABLE_NLS
391 #ifdef WIN32
392     RegistryTool rt;
393     rt.setPathInfo();
394     gchar *pathBuf = g_strconcat(g_path_get_dirname(argv[0]), "\\", PACKAGE_LOCALE_DIR, NULL);
395     bindtextdomain(GETTEXT_PACKAGE, pathBuf);
396     g_free(pathBuf);
397 #else
398 #ifdef ENABLE_BINRELOC
399     bindtextdomain(GETTEXT_PACKAGE, BR_LOCALEDIR(""));
400 #else
401     bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
402 #endif
403 #endif
404 #endif
406     bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
408 #ifdef ENABLE_NLS
409     textdomain(GETTEXT_PACKAGE);
410 #endif
412     LIBXML_TEST_VERSION
414     Inkscape::GC::init();
416     Inkscape::Debug::Logger::init();
418     gboolean use_gui;
419 #ifndef WIN32
420     use_gui = (getenv("DISPLAY") != NULL);
421 #else
422     /*
423       Set the current directory to the directory of the
424       executable.  This seems redundant, but is needed for
425       when inkscape.exe is executed from another directory.
426       We use relative paths on win32.
427       HKCR\svgfile\shell\open\command is a good example
428     */
429     /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
430     char *homedir = g_path_get_dirname(argv[0]);
431     SetCurrentDirectory(homedir);
432     g_free(homedir);
434     use_gui = TRUE;
435 #endif
436     /* Test whether with/without GUI is forced */
437     for (int i = 1; i < argc; i++) {
438         if (!strcmp(argv[i], "-z")
439             || !strcmp(argv[i], "--without-gui")
440             || !strcmp(argv[i], "-p")
441             || !strncmp(argv[i], "--print", 7)
442             || !strcmp(argv[i], "-e")
443             || !strncmp(argv[i], "--export-png", 12)
444             || !strcmp(argv[i], "-l")
445             || !strncmp(argv[i], "--export-plain-svg", 12)
446             || !strcmp(argv[i], "-i")
447             || !strncmp(argv[i], "--export-area-drawing", 21)
448             || !strcmp(argv[i], "-D")
449             || !strncmp(argv[i], "--export-area-canvas", 20)
450             || !strcmp(argv[i], "-C")
451             || !strncmp(argv[i], "--export-id", 12)
452             || !strcmp(argv[i], "-P")
453             || !strncmp(argv[i], "--export-ps", 11)
454             || !strcmp(argv[i], "-E")
455             || !strncmp(argv[i], "--export-eps", 12)
456             || !strcmp(argv[i], "-A")
457             || !strncmp(argv[i], "--export-pdf", 12)
458             || !strcmp(argv[i], "-W")
459             || !strncmp(argv[i], "--query-width", 13)
460             || !strcmp(argv[i], "-H")
461             || !strncmp(argv[i], "--query-height", 14)
462             || !strcmp(argv[i], "-X")
463             || !strncmp(argv[i], "--query-x", 13)
464             || !strcmp(argv[i], "-Y")
465             || !strncmp(argv[i], "--query-y", 14)
466             || !strcmp(argv[i], "--vacuum-defs")
467            )
468         {
469             /* main_console handles any exports -- not the gui */
470             use_gui = FALSE;
471             break;
472         } else if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--with-gui")) {
473             use_gui = TRUE;
474             break;
475         }
476     }
478 #ifdef WIN32
479 #ifndef REPLACEARGS_ANSI
480     if ( PrintWin32::is_os_wide() )
481 #endif // REPLACEARGS_ANSI
482     {
483         // If the call fails, we'll need to convert charsets
484         needToRecodeParams = !replaceArgs( argc, argv );
485     }
486 #endif // WIN32
488     /// \todo  Should this be a static object (see inkscape.cpp)?
489     Inkscape::NSApplication::Application app(argc, argv, use_gui, sp_new_gui);
491     return app.run();
494 void fixupSingleFilename( gchar **orig, gchar **spare )
496     if ( orig && *orig && **orig ) {
497         GError *error = NULL;
498         gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(*orig, -1, NULL, NULL, &error);
499         if ( newFileName )
500         {
501             *orig = newFileName;
502             if ( spare ) {
503                 *spare = newFileName;
504             }
505 //             g_message("Set a replacement fixup");
506         }
507     }
510 GSList *fixupFilenameEncoding( GSList* fl )
512     GSList *newFl = NULL;
513     while ( fl ) {
514         gchar *fn = static_cast<gchar*>(fl->data);
515         fl = g_slist_remove( fl, fl->data );
516         gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(fn, -1, NULL, NULL, NULL);
517         if ( newFileName ) {
519             if ( 0 )
520             {
521                 gchar *safeFn = Inkscape::IO::sanitizeString(fn);
522                 gchar *safeNewFn = Inkscape::IO::sanitizeString(newFileName);
523                 GtkWidget *w = gtk_message_dialog_new( NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
524                                                        "Note: Converted '%s' to '%s'", safeFn, safeNewFn );
525                 gtk_dialog_run (GTK_DIALOG (w));
526                 gtk_widget_destroy (w);
527                 g_free(safeNewFn);
528                 g_free(safeFn);
529             }
531             g_free( fn );
532             fn = newFileName;
533             newFileName = 0;
534         }
535         else
536             if ( 0 )
537         {
538             gchar *safeFn = Inkscape::IO::sanitizeString(fn);
539             GtkWidget *w = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "Error: Unable to convert '%s'", safeFn );
540             gtk_dialog_run (GTK_DIALOG (w));
541             gtk_widget_destroy (w);
542             g_free(safeFn);
543         }
544         newFl = g_slist_append( newFl, fn );
545     }
546     return newFl;
549 int sp_common_main( int argc, char const **argv, GSList **flDest )
551     /// \todo fixme: Move these to some centralized location (Lauris)
552     sp_object_type_register("sodipodi:namedview", SP_TYPE_NAMEDVIEW);
553     sp_object_type_register("sodipodi:guide", SP_TYPE_GUIDE);
556     // temporarily switch gettext encoding to locale, so that help messages can be output properly
557     gchar const *charset;
558     g_get_charset(&charset);
560     bind_textdomain_codeset(GETTEXT_PACKAGE, charset);
562     poptContext ctx = poptGetContext(NULL, argc, argv, options, 0);
563     poptSetOtherOptionHelp(ctx, _("[OPTIONS...] [FILE...]\n\nAvailable options:"));
564     g_return_val_if_fail(ctx != NULL, 1);
566     /* Collect own arguments */
567     GSList *fl = sp_process_args(ctx);
568     poptFreeContext(ctx);
570     // now switch gettext back to UTF-8 (for GUI)
571     bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
573     // Now let's see if the file list still holds up
574     if ( needToRecodeParams )
575     {
576         fl = fixupFilenameEncoding( fl );
577     }
579     // Check the globals for filename-fixup
580     if ( needToRecodeParams )
581     {
582         fixupSingleFilename( &sp_export_png, &sp_export_png_utf8 );
583         fixupSingleFilename( &sp_export_svg, &sp_export_svg_utf8 );
584         fixupSingleFilename( &sp_global_printer, &sp_global_printer_utf8 );
585     }
586     else
587     {
588         if ( sp_export_png )
589             sp_export_png_utf8 = g_strdup( sp_export_png );
590         if ( sp_export_svg )
591             sp_export_svg_utf8 = g_strdup( sp_export_svg );
592         if ( sp_global_printer )
593             sp_global_printer_utf8 = g_strdup( sp_global_printer );
594     }
596     // Return the list if wanted, else free it up.
597     if ( flDest ) {
598         *flDest = fl;
599         fl = 0;
600     } else {
601         while ( fl ) {
602             g_free( fl->data );
603             fl = g_slist_remove( fl, fl->data );
604         }
605     }
606     return 0;
609 int
610 sp_main_gui(int argc, char const **argv)
612     Gtk::Main main_instance (&argc, const_cast<char ***>(&argv));
614     GSList *fl = NULL;
615     int retVal = sp_common_main( argc, argv, &fl );
616     g_return_val_if_fail(retVal == 0, 1);
618     inkscape_gtk_stock_init();
620     /* Set default icon */
621     gchar *filename = (gchar *) g_build_filename (INKSCAPE_APPICONDIR, "inkscape.png", NULL);
622     if (Inkscape::IO::file_test(filename, (GFileTest)(G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK))) {
623         gtk_window_set_default_icon_from_file(filename, NULL);
624     }
625     g_free (filename);
626     filename = 0;
628     if (!sp_global_slideshow) {
629         gboolean create_new = TRUE;
631         /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
632         inkscape_application_init(argv[0], true);
634         while (fl) {
635             if (sp_file_open((gchar *)fl->data,NULL)) {
636                 create_new=FALSE;
637             }
638             fl = g_slist_remove(fl, fl->data);
639         }
640         if (create_new) {
641             sp_file_new_default();
642         }
643     } else {
644         if (fl) {
645             GtkWidget *ss;
646             /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
647             inkscape_application_init(argv[0], true);
648             ss = sp_slideshow_new(fl);
649             if (ss) gtk_widget_show(ss);
650         } else {
651             g_warning ("No slides to display");
652             exit(0);
653         }
654     }
656     main_instance.run();
658 #ifdef WIN32
659     //We might not need anything here
660     //sp_win32_finish(); <-- this is a NOP func
661 #endif
663     return 0;
666 int
667 sp_main_console(int argc, char const **argv)
669     /* We are started in text mode */
671     /* Do this g_type_init(), so that we can use Xft/Freetype2 (Pango)
672      * in a non-Gtk environment.  Used in libnrtype's
673      * FontInstance.cpp and FontFactory.cpp.
674      * http://mail.gnome.org/archives/gtk-list/2003-December/msg00063.html
675      */
676     g_type_init();
677     char **argv2 = const_cast<char **>(argv);
678     gtk_init_check( &argc, &argv2 );
679     //setlocale(LC_ALL, "");
681     GSList *fl = NULL;
682     int retVal = sp_common_main( argc, argv, &fl );
683     g_return_val_if_fail(retVal == 0, 1);
685     if (fl == NULL) {
686         g_print("Nothing to do!\n");
687         exit(0);
688     }
690     inkscape_application_init(argv[0], false);
692     while (fl) {
693         SPDocument *doc;
695         doc = Inkscape::Extension::open(NULL, (gchar *)fl->data);
696         if (doc == NULL) {
697             doc = Inkscape::Extension::open(Inkscape::Extension::db.get(SP_MODULE_KEY_INPUT_SVG), (gchar *)fl->data);
698         }
699         if (doc == NULL) {
700             g_warning("Specified document %s cannot be opened (is it valid SVG file?)", (gchar *) fl->data);
701         } else {
702             if (sp_vacuum_defs) {
703                 vacuum_document(doc);
704             }
705             if (sp_vacuum_defs && !sp_export_svg) {
706                 // save under the name given in the command line
707                 sp_repr_save_file(doc->rdoc, (gchar *)fl->data, SP_SVG_NS_URI);
708             }
709             if (sp_global_printer) {
710                 sp_print_document_to_file(doc, sp_global_printer);
711             }
712             if (sp_export_png || sp_export_id || sp_export_area_drawing) {
713                 sp_do_export_png(doc);
714             }
715             if (sp_export_svg) {
716                 Inkscape::XML::Document *rdoc;
717                 Inkscape::XML::Node *repr;
718                 rdoc = sp_repr_document_new("svg:svg");
719                 repr = rdoc->root();
720                 repr = sp_document_root(doc)->updateRepr(repr, SP_OBJECT_WRITE_BUILD);
721                 sp_repr_save_file(repr->document(), sp_export_svg, SP_SVG_NS_URI);
722             }
723             if (sp_export_ps) {
724                 do_export_ps(doc, sp_export_ps, "image/x-postscript");
725             }
726             if (sp_export_eps) {
727                 do_export_ps(doc, sp_export_eps, "image/x-e-postscript");
728             }
729             if (sp_export_pdf) {
730                 do_export_pdf(doc, sp_export_pdf, "application/pdf");
731             }
732             if (sp_query_width || sp_query_height) {
733                 do_query_dimension (doc, true, sp_query_width? NR::X : NR::Y, sp_query_id);
734             } else if (sp_query_x || sp_query_y) {
735                 do_query_dimension (doc, false, sp_query_x? NR::X : NR::Y, sp_query_id);
736             }
737         }
738         fl = g_slist_remove(fl, fl->data);
739     }
741     inkscape_unref();
743     return 0;
746 static void
747 do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gchar *id)
749     SPObject *o = NULL;
751     if (id) {
752         o = doc->getObjectById(id);
753         if (o) {
754             if (!SP_IS_ITEM (o)) {
755                 g_warning("Object with id=\"%s\" is not a visible item. Cannot query dimensions.", id);
756                 return;
757             }
758         } else {
759             g_warning("Object with id=\"%s\" is not found. Cannot query dimensions.", id);
760             return;
761         }
762     } else {
763         o = SP_DOCUMENT_ROOT(doc);
764     }
766     if (o) {
767         sp_document_ensure_up_to_date (doc);
768         SPItem *item = ((SPItem *) o);
769         NR::Rect area = item->invokeBbox(sp_item_i2doc_affine(item)); // "true" SVG bbox for scripting
771         Inkscape::SVGOStringStream os;
772         if (extent) {
773             os << area.extent(axis);
774         } else {
775             os << area.min()[axis];
776         }
777         g_print ("%s", os.str().c_str());
778     }
782 static void
783 sp_do_export_png(SPDocument *doc)
785     const gchar *filename = NULL;
786     gdouble dpi = 0.0;
788     if (sp_export_use_hints && (!sp_export_id && !sp_export_area_drawing)) {
789         g_warning ("--export-use-hints can only be used with --export-id or --export-area-drawing; ignored.");
790     }
792     GSList *items = NULL;
794     NRRect area;
795     if (sp_export_id || sp_export_area_drawing) {
797         SPObject *o = NULL;
798         SPObject *o_area = NULL;
799         if (sp_export_id && sp_export_area_drawing) {
800             o = doc->getObjectById(sp_export_id);
801             o_area = SP_DOCUMENT_ROOT (doc);
802         } else if (sp_export_id) {
803             o = doc->getObjectById(sp_export_id);
804             o_area = o;
805         } else if (sp_export_area_drawing) {
806             o = SP_DOCUMENT_ROOT (doc);
807             o_area = o;
808         } 
810         if (o) {
811             if (!SP_IS_ITEM (o)) {
812                 g_warning("Object with id=\"%s\" is not a visible item. Nothing exported.", sp_export_id);
813                 return;
814             }
816             items = g_slist_prepend (items, SP_ITEM(o));
818             if (sp_export_id_only) {
819                 g_print("Exporting only object with id=\"%s\"; all other objects hidden\n", sp_export_id);
820             }
822             if (sp_export_use_hints) {
824                 // retrieve export filename hint
825                 const gchar *fn_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-filename");
826                 if (fn_hint) {
827                     if (sp_export_png) {
828                         g_warning ("Using export filename from the command line (--export-png). Filename hint %s is ignored.", fn_hint);
829                         filename = sp_export_png;
830                     } else {
831                         filename = fn_hint;
832                     }
833                 } else {
834                     g_warning ("Export filename hint not found for the object.");
835                     filename = sp_export_png;
836                 }
838                 // retrieve export dpi hints
839                 const gchar *dpi_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-xdpi"); // only xdpi, ydpi is always the same now
840                 if (dpi_hint) {
841                     if (sp_export_dpi || sp_export_width || sp_export_height) {
842                         g_warning ("Using bitmap dimensions from the command line (--export-dpi, --export-width, or --export-height). DPI hint %s is ignored.", dpi_hint);
843                     } else {
844                         dpi = atof(dpi_hint);
845                     }
846                 } else {
847                     g_warning ("Export DPI hint not found for the object.");
848                 }
850             }
852             // write object bbox to area
853             sp_document_ensure_up_to_date (doc);
854             sp_item_invoke_bbox((SPItem *) o_area, &area, sp_item_i2r_affine((SPItem *) o_area), TRUE);
855         } else {
856             g_warning("Object with id=\"%s\" was not found in the document. Nothing exported.", sp_export_id);
857             return;
858         }
859     }
860     
861     if (sp_export_area) {
862         /* Try to parse area (given in SVG pixels) */
863         if (!sscanf(sp_export_area, "%lg:%lg:%lg:%lg", &area.x0, &area.y0, &area.x1, &area.y1) == 4) {
864             g_warning("Cannot parse export area '%s'; use 'x0:y0:x1:y1'. Nothing exported.", sp_export_area);
865             return;
866         }
867         if ((area.x0 >= area.x1) || (area.y0 >= area.y1)) {
868             g_warning("Export area '%s' has negative width or height. Nothing exported.", sp_export_area);
869             return;
870         }
871     } else if (sp_export_area_canvas || !(sp_export_id || sp_export_area_drawing)) {
872         /* Export the whole canvas */
873         sp_document_ensure_up_to_date (doc);
874         area.x0 = SP_ROOT(doc->root)->x.computed;
875         area.y0 = SP_ROOT(doc->root)->y.computed;
876         area.x1 = area.x0 + sp_document_width (doc);
877         area.y1 = area.y0 + sp_document_height (doc);
878     }
880     // set filename and dpi from options, if not yet set from the hints
881     if (!filename) {
882         if (!sp_export_png) {
883             g_warning ("No export filename given and no filename hint. Nothing exported.");
884             return;
885         }
886         filename = sp_export_png;
887     }
889     if (sp_export_dpi && dpi == 0.0) {
890         dpi = atof(sp_export_dpi);
891         if ((dpi < 0.1) || (dpi > 10000.0)) {
892             g_warning("DPI value %s out of range [0.1 - 10000.0]. Nothing exported.", sp_export_dpi);
893             return;
894         }
895         g_print("DPI: %g\n", dpi);
896     }
898     if (sp_export_area_snap) {
899         area.x0 = std::floor (area.x0);
900         area.y0 = std::floor (area.y0);
901         area.x1 = std::ceil (area.x1);
902         area.y1 = std::ceil (area.y1);
903     }
905     // default dpi
906     if (dpi == 0.0)
907         dpi = PX_PER_IN;
909     gint width = 0;
910     gint height = 0;
912     if (sp_export_width) {
913         width = atoi(sp_export_width);
914         if ((width < 1) || (width > 65536)) {
915             g_warning("Export width %d out of range (1 - 65536). Nothing exported.", width);
916             return;
917         }
918         dpi = (gdouble) width * PX_PER_IN / (area.x1 - area.x0);
919     }
921     if (sp_export_height) {
922         height = atoi(sp_export_height);
923         if ((height < 1) || (height > 65536)) {
924             g_warning("Export height %d out of range (1 - 65536). Nothing exported.", width);
925             return;
926         }
927         dpi = (gdouble) height * PX_PER_IN / (area.y1 - area.y0);
928     }
930     if (!sp_export_width) {
931         width = (gint) ((area.x1 - area.x0) * dpi / PX_PER_IN + 0.5);
932     }
934     if (!sp_export_height) {
935         height = (gint) ((area.y1 - area.y0) * dpi / PX_PER_IN + 0.5);
936     }
938     guint32 bgcolor = 0x00000000;
939     if (sp_export_background) {
940         // override the page color
941         bgcolor = sp_svg_read_color(sp_export_background, 0xffffff00);
942         bgcolor |= 0xff; // default is no opacity
943     } else {
944         // read from namedview
945         Inkscape::XML::Node *nv = sp_repr_lookup_name (doc->rroot, "sodipodi:namedview");
946         if (nv && nv->attribute("pagecolor"))
947             bgcolor = sp_svg_read_color(nv->attribute("pagecolor"), 0xffffff00);
948         if (nv && nv->attribute("inkscape:pageopacity"))
949             bgcolor |= SP_COLOR_F_TO_U(sp_repr_get_double_attribute (nv, "inkscape:pageopacity", 1.0));
950     }
952     if (sp_export_background_opacity) {
953         // override opacity
954         gfloat value;
955         if (sp_svg_number_read_f (sp_export_background_opacity, &value)) {
956             if (value > 1.0) {
957                 value = CLAMP (value, 1.0f, 255.0f);
958                 bgcolor &= (guint32) 0xffffff00;
959                 bgcolor |= (guint32) floor(value);
960             } else {
961                 value = CLAMP (value, 0.0f, 1.0f);
962                 bgcolor &= (guint32) 0xffffff00;
963                 bgcolor |= SP_COLOR_F_TO_U(value);
964             }
965         }
966     }
968     g_print("Background RRGGBBAA: %08x\n", bgcolor);
970     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);
972     g_print("Bitmap saved as: %s\n", filename);
974     if ((width >= 1) && (height >= 1) && (width < 65536) && (height < 65536)) {
975         sp_export_png_file(doc, filename, area.x0, area.y0, area.x1, area.y1, width, height, dpi, dpi, bgcolor, NULL, NULL, true, sp_export_id_only ? items : NULL);
976     } else {
977         g_warning("Calculated bitmap dimensions %d %d are out of range (1 - 65535). Nothing exported.", width, height);
978     }
980     g_slist_free (items);
984 /**
985  *  Perform an export of either PS or EPS.
986  *
987  *  \param doc Document to export.
988  *  \param uri URI to export to.
989  *  \param mime MIME type to export as.
990  */
992 static void do_export_ps(SPDocument* doc, gchar const* uri, char const* mime)
994     Inkscape::Extension::DB::OutputList o;
995     Inkscape::Extension::db.get_output_list(o);
996     Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
997     while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
998         i++;
999     }
1001     if (i == o.end())
1002     {
1003         g_warning ("Could not find an extension to export this file.");
1004         return;
1005     }
1007     bool old_text_to_path = false;
1008     bool old_font_embedded = false;
1009     bool old_bbox_page = false;
1011     try {
1012         old_text_to_path = (*i)->get_param_bool("textToPath");
1013         (*i)->set_param_bool("textToPath", sp_export_text_to_path);
1014     }
1015     catch (...) {
1016         g_warning ("Could not set export-text-to-path option for this export.");
1017     }
1019     try {
1020         old_font_embedded = (*i)->get_param_bool("fontEmbedded");
1021         (*i)->set_param_bool("fontEmbedded", sp_export_font);
1022     }
1023     catch (...) {
1024         g_warning ("Could not set export-font option for this export.");
1025     }
1027     try {
1028         old_bbox_page = (*i)->get_param_bool("pageBoundingBox");
1029         (*i)->set_param_bool("pageBoundingBox", sp_export_bbox_page);
1030     }
1031     catch (...) {
1032         g_warning ("Could not set export-bbox-page option for this export.");
1033     }
1035     (*i)->save(doc, uri);
1037     try {
1038         (*i)->set_param_bool("textToPath", old_text_to_path);
1039         (*i)->set_param_bool("fontEmbedded", old_font_embedded);
1040         (*i)->set_param_bool("pageBoundingBox", old_bbox_page);
1041     }
1042     catch (...) {
1044     }
1047 /**
1048  *  Perform a PDF export
1049  *
1050  *  \param doc Document to export.
1051  *  \param uri URI to export to.
1052  *  \param mime MIME type to export as.
1053  */
1055 static void do_export_pdf(SPDocument* doc, gchar const* uri, char const* mime)
1057     Inkscape::Extension::DB::OutputList o;
1058     Inkscape::Extension::db.get_output_list(o);
1059     Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
1060     while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
1061         i++;
1062     }
1064     if (i == o.end())
1065     {
1066         g_warning ("Could not find an extension to export this file.");
1067         return;
1068     }
1070     (*i)->save(doc, uri);
1073 #ifdef WIN32
1074 bool replaceArgs( int& argc, char**& argv )
1076     bool worked = false;
1078 #ifdef REPLACEARGS_DEBUG
1079     MessageBoxA( NULL, "GetCommandLineW() getting called", "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1080 #endif // REPLACEARGS_DEBUG
1082     wchar_t* line = GetCommandLineW();
1083     if ( line )
1084     {
1085 #ifdef REPLACEARGS_DEBUG
1086         {
1087             gchar* utf8Line = g_utf16_to_utf8( (gunichar2*)line, -1, NULL, NULL, NULL );
1088             if ( utf8Line )
1089             {
1090                 gchar *safe = Inkscape::IO::sanitizeString(utf8Line);
1091                 {
1092                     char tmp[strlen(safe) + 32];
1093                     snprintf( tmp, sizeof(tmp), "GetCommandLineW() = '%s'", safe );
1094                     MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1095                 }
1096             }
1097         }
1098 #endif // REPLACEARGS_DEBUG
1100         int numArgs = 0;
1101         wchar_t** parsed = CommandLineToArgvW( line, &numArgs );
1103 #ifdef REPLACEARGS_ANSI
1104 // test code for trying things on Win95/98/ME
1105         if ( !parsed )
1106         {
1107 #ifdef REPLACEARGS_DEBUG
1108             MessageBoxA( NULL, "Unable to process command-line. Faking it", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1109 #endif // REPLACEARGS_DEBUG
1110             int lineLen = wcslen(line) + 1;
1111             wchar_t* lineDup = new wchar_t[lineLen];
1112             wcsncpy( lineDup, line, lineLen );
1114             int pos = 0;
1115             bool inQuotes = false;
1116             bool inWhitespace = true;
1117             std::vector<int> places;
1118             while ( lineDup[pos] )
1119             {
1120                 if ( inQuotes )
1121                 {
1122                     if ( lineDup[pos] == L'"' )
1123                     {
1124                         inQuotes = false;
1125                     }
1126                 }
1127                 else if ( lineDup[pos] == L'"' )
1128                 {
1129                     inQuotes = true;
1130                     inWhitespace = false;
1131                     places.push_back(pos);
1132                 }
1133                 else if ( lineDup[pos] == L' ' || lineDup[pos] == L'\t' )
1134                 {
1135                     if ( !inWhitespace )
1136                     {
1137                         inWhitespace = true;
1138                         lineDup[pos] = 0;
1139                     }
1140                 }
1141                 else if ( inWhitespace && (lineDup[pos] != L' ' && lineDup[pos] != L'\t') )
1142                 {
1143                     inWhitespace = false;
1144                     places.push_back(pos);
1145                 }
1146                 else
1147                 {
1148                     // consume
1149                 }
1150                 pos++;
1151             }
1152 #ifdef REPLACEARGS_DEBUG
1153             {
1154                 char tmp[256];
1155                 snprintf( tmp, sizeof(tmp), "Counted %d args", places.size() );
1156                 MessageBoxA( NULL, tmp, "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1157             }
1158 #endif // REPLACEARGS_DEBUG
1160             wchar_t** block = new wchar_t*[places.size()];
1161             int i = 0;
1162             for ( std::vector<int>::iterator it = places.begin(); it != places.end(); it++ )
1163             {
1164                 block[i++] = &lineDup[*it];
1165             }
1166             parsed = block;
1167             numArgs = places.size();
1168         }
1169 #endif // REPLACEARGS_ANSI
1171         if ( parsed )
1172         {
1173             std::vector<wchar_t*>expandedArgs;
1174             if ( numArgs > 0 )
1175             {
1176                 expandedArgs.push_back( parsed[0] );
1177             }
1179             for ( int i1 = 1; i1 < numArgs; i1++ )
1180             {
1181                 bool wildcarded = (wcschr(parsed[i1], L'?') != NULL) || (wcschr(parsed[i1], L'*') != NULL);
1182                 wildcarded &= parsed[i1][0] != L'"';
1183                 wildcarded &= parsed[i1][0] != L'-';
1184                 if ( wildcarded )
1185                 {
1186 #ifdef REPLACEARGS_ANSI
1187                     WIN32_FIND_DATAA data = {0};
1188 #else
1189                     WIN32_FIND_DATAW data = {0};
1190 #endif // REPLACEARGS_ANSI
1192                     int baseLen = wcslen(parsed[i1]) + 2;
1193                     wchar_t* base = new wchar_t[baseLen];
1194                     wcsncpy( base, parsed[i1], baseLen );
1195                     wchar_t* last = wcsrchr( base, L'\\' );
1196                     if ( last )
1197                     {
1198                         last[1] = 0;
1199                     }
1200                     else
1201                     {
1202                         base[0] = 0;
1203                     }
1204                     baseLen = wcslen( base );
1206 #ifdef REPLACEARGS_ANSI
1207                     char target[MAX_PATH];
1208                     if ( WideCharToMultiByte( CP_ACP, 0, parsed[i1], -1, target, sizeof(target), NULL, NULL) )
1209                     {
1210                         HANDLE hf = FindFirstFileA( target, &data );
1211 #else
1212                         HANDLE hf = FindFirstFileW( parsed[i1], &data );
1213 #endif // REPLACEARGS_ANSI
1214                         if ( hf != INVALID_HANDLE_VALUE )
1215                         {
1216                             BOOL found = TRUE;
1217                             do
1218                             {
1219 #ifdef REPLACEARGS_ANSI
1220                                 int howMany = MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, NULL, 0 );
1221                                 if ( howMany > 0 )
1222                                 {
1223                                     howMany += baseLen;
1224                                     wchar_t* tmp = new wchar_t[howMany + 1];
1225                                     wcsncpy( tmp, base, howMany + 1 );
1226                                     MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, tmp + baseLen, howMany + 1 - baseLen );
1227                                     expandedArgs.push_back( tmp );
1228                                     found = FindNextFileA( hf, &data );
1229                                 }
1230 #else
1231                                 int howMany = wcslen(data.cFileName) + baseLen;
1232                                 wchar_t* tmp = new wchar_t[howMany + 1];
1233                                 wcsncpy( tmp, base, howMany + 1 );
1234                                 wcsncat( tmp, data.cFileName, howMany + 1 );
1235                                 expandedArgs.push_back( tmp );
1236                                 found = FindNextFileW( hf, &data );
1237 #endif // REPLACEARGS_ANSI
1238                             } while ( found );
1240                             FindClose( hf );
1241                         }
1242                         else
1243                         {
1244                             expandedArgs.push_back( parsed[i1] );
1245                         }
1246 #ifdef REPLACEARGS_ANSI
1247                     }
1248 #endif // REPLACEARGS_ANSI
1250                     delete[] base;
1251                 }
1252                 else
1253                 {
1254                     expandedArgs.push_back( parsed[i1] );
1255                 }
1256             }
1258             {
1259                 wchar_t** block = new wchar_t*[expandedArgs.size()];
1260                 int iz = 0;
1261                 for ( std::vector<wchar_t*>::iterator it = expandedArgs.begin(); it != expandedArgs.end(); it++ )
1262                 {
1263                     block[iz++] = *it;
1264                 }
1265                 parsed = block;
1266                 numArgs = expandedArgs.size();
1267             }
1269             std::vector<gchar*> newArgs;
1270             for ( int i = 0; i < numArgs; i++ )
1271             {
1272                 gchar* replacement = g_utf16_to_utf8( (gunichar2*)parsed[i], -1, NULL, NULL, NULL );
1273                 if ( replacement )
1274                 {
1275 #ifdef REPLACEARGS_DEBUG
1276                     gchar *safe2 = Inkscape::IO::sanitizeString(replacement);
1278                     if ( safe2 )
1279                     {
1280                         {
1281                             char tmp[1024];
1282                             snprintf( tmp, sizeof(tmp), "    [%2d] = '%s'", i, safe2 );
1283                             MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1284                         }
1285                         g_free( safe2 );
1286                     }
1287 #endif // REPLACEARGS_DEBUG
1289                     newArgs.push_back( replacement );
1290                 }
1291                 else
1292                 {
1293                     newArgs.push_back( blankParam );
1294                 }
1295             }
1297             // Now push our munged params to be the new argv and argc
1298             {
1299                 char** block = new char*[newArgs.size()];
1300                 int iz = 0;
1301                 for ( std::vector<char*>::iterator it = newArgs.begin(); it != newArgs.end(); it++ )
1302                 {
1303                     block[iz++] = *it;
1304                 }
1305                 argv = block;
1306                 argc = newArgs.size();
1307                 worked = true;
1308             }
1309         }
1310 #ifdef REPLACEARGS_DEBUG
1311         else
1312         {
1313             MessageBoxA( NULL, "Unable to process command-line", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1314         }
1315 #endif // REPLACEARGS_DEBUG
1316     }
1317 #ifdef REPLACEARGS_DEBUG
1318     else
1319     {
1320         {
1321             MessageBoxA( NULL,  "Unable to fetch result from GetCommandLineW()", "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1322         }
1324         char* line2 = GetCommandLineA();
1325         if ( line2 )
1326         {
1327             gchar *safe = Inkscape::IO::sanitizeString(line2);
1328             {
1329                 {
1330                     char tmp[strlen(safe) + 32];
1331                     snprintf( tmp, sizeof(tmp), "GetCommandLineA() = '%s'", safe );
1332                     MessageBoxA( NULL, tmp, "GetCommandLineA", MB_OK | MB_ICONINFORMATION );
1333                 }
1334             }
1335         }
1336         else
1337         {
1338             MessageBoxA( NULL, "Unable to fetch result from GetCommandLineA()", "GetCommandLineA", MB_OK | MB_ICONINFORMATION );
1339         }
1340     }
1341 #endif // REPLACEARGS_DEBUG
1343     return worked;
1345 #endif // WIN32
1347 static GSList *
1348 sp_process_args(poptContext ctx)
1350     GSList *fl = NULL;
1352     gint a;
1353     while ((a = poptGetNextOpt(ctx)) >= 0) {
1354         switch (a) {
1355             case SP_ARG_FILE: {
1356                 gchar const *fn = poptGetOptArg(ctx);
1357                 if (fn != NULL) {
1358                     fl = g_slist_append(fl, g_strdup(fn));
1359                 }
1360                 break;
1361             }
1362             case SP_ARG_VERSION: {
1363                 printf("Inkscape %s (%s)\n", INKSCAPE_VERSION, __DATE__);
1364                 exit(0);
1365                 break;
1366             }
1367             case SP_ARG_EXTENSIONDIR: {
1368                 printf("%s\n", INKSCAPE_EXTENSIONDIR);
1369                 exit(0);
1370                 break;
1371             }
1372             default: {
1373                 break;
1374             }
1375         }
1376     }
1378     gchar const ** const args = poptGetArgs(ctx);
1379     if (args != NULL) {
1380         for (unsigned i = 0; args[i] != NULL; i++) {
1381             fl = g_slist_append(fl, g_strdup(args[i]));
1382         }
1383     }
1385     return fl;
1389 /*
1390   Local Variables:
1391   mode:c++
1392   c-file-style:"stroustrup"
1393   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
1394   indent-tabs-mode:nil
1395   fill-column:99
1396   End:
1397 */
1398 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :