Code

e8f75c75666cf16a09eaa44aaec72829f03f9268
[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     {"query-x", 'X',
325      POPT_ARG_NONE, &sp_query_x, SP_ARG_QUERY_X,
326      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
327      N_("Query the X coordinate of the drawing or, if specified, of the object with --query-id"),
328      NULL},
330     {"query-y", 'Y',
331      POPT_ARG_NONE, &sp_query_y, SP_ARG_QUERY_Y,
332      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
333      N_("Query the Y coordinate of the drawing or, if specified, of the object with --query-id"),
334      NULL},
336     {"query-width", 'W',
337      POPT_ARG_NONE, &sp_query_width, SP_ARG_QUERY_WIDTH,
338      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
339      N_("Query the width of the drawing or, if specified, of the object with --query-id"),
340      NULL},
342     {"query-height", 'H',
343      POPT_ARG_NONE, &sp_query_height, SP_ARG_QUERY_HEIGHT,
344      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
345      N_("Query the height of the drawing or, if specified, of the object with --query-id"),
346      NULL},
348     {"query-id", 'I',
349      POPT_ARG_STRING, &sp_query_id, SP_ARG_QUERY_ID,
350      N_("The ID of the object whose dimensions are queried"),
351      N_("ID")},
353     {"extension-directory", 'x',
354      POPT_ARG_NONE, NULL, SP_ARG_EXTENSIONDIR,
355      // TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory
356      N_("Print out the extension directory and exit"),
357      NULL},
359     {"slideshow", 's',
360      POPT_ARG_NONE, &sp_global_slideshow, SP_ARG_SLIDESHOW,
361      N_("Show given files one-by-one, switch to next on any key/mouse event"),
362      NULL},
364     {"vacuum-defs", 0,
365      POPT_ARG_NONE, &sp_vacuum_defs, SP_ARG_VACUUM_DEFS,
366      N_("Remove unused definitions from the defs section(s) of the document"),
367      NULL},
369     POPT_AUTOHELP POPT_TABLEEND
370 };
372 static bool needToRecodeParams = true;
373 gchar* blankParam = "";
375 int
376 main(int argc, char **argv)
378 #ifdef HAVE_FPSETMASK
379     /* This is inherited from Sodipodi code, where it was in #ifdef __FreeBSD__.  It's probably
380        safe to remove: the default mask is already 0 in C99, and in current FreeBSD according to
381        the fenv man page on www.freebsd.org, and in glibc according to (libc)FP Exceptions. */
382     fpsetmask(fpgetmask() & ~(FP_X_DZ | FP_X_INV));
383 #endif
385 #ifdef ENABLE_NLS
386 #ifdef WIN32
387     RegistryTool rt;
388     rt.setPathInfo();
389     gchar *pathBuf = g_strconcat(g_path_get_dirname(argv[0]), "\\", PACKAGE_LOCALE_DIR, NULL);
390     bindtextdomain(GETTEXT_PACKAGE, pathBuf);
391     g_free(pathBuf);
392 #else
393 #ifdef ENABLE_BINRELOC
394     bindtextdomain(GETTEXT_PACKAGE, BR_LOCALEDIR(""));
395 #else
396     bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
397 #endif
398 #endif
399 #endif
401     bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
403 #ifdef ENABLE_NLS
404     textdomain(GETTEXT_PACKAGE);
405 #endif
407     LIBXML_TEST_VERSION
409     Inkscape::GC::init();
411     Inkscape::Debug::Logger::init();
413     gboolean use_gui;
414 #ifndef WIN32
415     use_gui = (getenv("DISPLAY") != NULL);
416 #else
417     /*
418       Set the current directory to the directory of the
419       executable.  This seems redundant, but is needed for
420       when inkscape.exe is executed from another directory.
421       We use relative paths on win32.
422       HKCR\svgfile\shell\open\command is a good example
423     */
424     /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
425     char *homedir = g_path_get_dirname(argv[0]);
426     SetCurrentDirectory(homedir);
427     g_free(homedir);
429     use_gui = TRUE;
430 #endif
431     /* Test whether with/without GUI is forced */
432     for (int i = 1; i < argc; i++) {
433         if (!strcmp(argv[i], "-z")
434             || !strcmp(argv[i], "--without-gui")
435             || !strcmp(argv[i], "-p")
436             || !strncmp(argv[i], "--print", 7)
437             || !strcmp(argv[i], "-e")
438             || !strncmp(argv[i], "--export-png", 12)
439             || !strcmp(argv[i], "-l")
440             || !strncmp(argv[i], "--export-plain-svg", 12)
441             || !strcmp(argv[i], "-i")
442             || !strncmp(argv[i], "--export-area-drawing", 21)
443             || !strcmp(argv[i], "-D")
444             || !strncmp(argv[i], "--export-area-canvas", 20)
445             || !strcmp(argv[i], "-C")
446             || !strncmp(argv[i], "--export-id", 12)
447             || !strcmp(argv[i], "-P")
448             || !strncmp(argv[i], "--export-ps", 11)
449             || !strcmp(argv[i], "-E")
450             || !strncmp(argv[i], "--export-eps", 12)
451             || !strcmp(argv[i], "-A")
452             || !strncmp(argv[i], "--export-pdf", 12)
453             || !strcmp(argv[i], "-W")
454             || !strncmp(argv[i], "--query-width", 13)
455             || !strcmp(argv[i], "-H")
456             || !strncmp(argv[i], "--query-height", 14)
457             || !strcmp(argv[i], "-X")
458             || !strncmp(argv[i], "--query-x", 13)
459             || !strcmp(argv[i], "-Y")
460             || !strncmp(argv[i], "--query-y", 14)
461             || !strcmp(argv[i], "--vacuum-defs")
462            )
463         {
464             /* main_console handles any exports -- not the gui */
465             use_gui = FALSE;
466             break;
467         } else if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--with-gui")) {
468             use_gui = TRUE;
469             break;
470         }
471     }
473 #ifdef WIN32
474 #ifndef REPLACEARGS_ANSI
475     if ( PrintWin32::is_os_wide() )
476 #endif // REPLACEARGS_ANSI
477     {
478         // If the call fails, we'll need to convert charsets
479         needToRecodeParams = !replaceArgs( argc, argv );
480     }
481 #endif // WIN32
483     /// \todo  Should this be a static object (see inkscape.cpp)?
484     Inkscape::NSApplication::Application app(argc, argv, use_gui, sp_new_gui);
486     return app.run();
489 void fixupSingleFilename( gchar **orig, gchar **spare )
491     if ( orig && *orig && **orig ) {
492         GError *error = NULL;
493         gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(*orig, -1, NULL, NULL, &error);
494         if ( newFileName )
495         {
496             *orig = newFileName;
497             if ( spare ) {
498                 *spare = newFileName;
499             }
500 //             g_message("Set a replacement fixup");
501         }
502     }
505 GSList *fixupFilenameEncoding( GSList* fl )
507     GSList *newFl = NULL;
508     while ( fl ) {
509         gchar *fn = static_cast<gchar*>(fl->data);
510         fl = g_slist_remove( fl, fl->data );
511         gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(fn, -1, NULL, NULL, NULL);
512         if ( newFileName ) {
514             if ( 0 )
515             {
516                 gchar *safeFn = Inkscape::IO::sanitizeString(fn);
517                 gchar *safeNewFn = Inkscape::IO::sanitizeString(newFileName);
518                 GtkWidget *w = gtk_message_dialog_new( NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
519                                                        "Note: Converted '%s' to '%s'", safeFn, safeNewFn );
520                 gtk_dialog_run (GTK_DIALOG (w));
521                 gtk_widget_destroy (w);
522                 g_free(safeNewFn);
523                 g_free(safeFn);
524             }
526             g_free( fn );
527             fn = newFileName;
528             newFileName = 0;
529         }
530         else
531             if ( 0 )
532         {
533             gchar *safeFn = Inkscape::IO::sanitizeString(fn);
534             GtkWidget *w = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "Error: Unable to convert '%s'", safeFn );
535             gtk_dialog_run (GTK_DIALOG (w));
536             gtk_widget_destroy (w);
537             g_free(safeFn);
538         }
539         newFl = g_slist_append( newFl, fn );
540     }
541     return newFl;
544 int sp_common_main( int argc, char const **argv, GSList **flDest )
546     /// \todo fixme: Move these to some centralized location (Lauris)
547     sp_object_type_register("sodipodi:namedview", SP_TYPE_NAMEDVIEW);
548     sp_object_type_register("sodipodi:guide", SP_TYPE_GUIDE);
551     // temporarily switch gettext encoding to locale, so that help messages can be output properly
552     gchar const *charset;
553     g_get_charset(&charset);
555     bind_textdomain_codeset(GETTEXT_PACKAGE, charset);
557     poptContext ctx = poptGetContext(NULL, argc, argv, options, 0);
558     poptSetOtherOptionHelp(ctx, _("[OPTIONS...] [FILE...]\n\nAvailable options:"));
559     g_return_val_if_fail(ctx != NULL, 1);
561     /* Collect own arguments */
562     GSList *fl = sp_process_args(ctx);
563     poptFreeContext(ctx);
565     // now switch gettext back to UTF-8 (for GUI)
566     bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
568     // Now let's see if the file list still holds up
569     if ( needToRecodeParams )
570     {
571         fl = fixupFilenameEncoding( fl );
572     }
574     // Check the globals for filename-fixup
575     if ( needToRecodeParams )
576     {
577         fixupSingleFilename( &sp_export_png, &sp_export_png_utf8 );
578         fixupSingleFilename( &sp_export_svg, &sp_export_svg_utf8 );
579         fixupSingleFilename( &sp_global_printer, &sp_global_printer_utf8 );
580     }
581     else
582     {
583         if ( sp_export_png )
584             sp_export_png_utf8 = g_strdup( sp_export_png );
585         if ( sp_export_svg )
586             sp_export_svg_utf8 = g_strdup( sp_export_svg );
587         if ( sp_global_printer )
588             sp_global_printer_utf8 = g_strdup( sp_global_printer );
589     }
591     // Return the list if wanted, else free it up.
592     if ( flDest ) {
593         *flDest = fl;
594         fl = 0;
595     } else {
596         while ( fl ) {
597             g_free( fl->data );
598             fl = g_slist_remove( fl, fl->data );
599         }
600     }
601     return 0;
604 int
605 sp_main_gui(int argc, char const **argv)
607     Gtk::Main main_instance (&argc, const_cast<char ***>(&argv));
609     GSList *fl = NULL;
610     int retVal = sp_common_main( argc, argv, &fl );
611     g_return_val_if_fail(retVal == 0, 1);
613     inkscape_gtk_stock_init();
615     /* Set default icon */
616     gchar *filename = (gchar *) g_build_filename (INKSCAPE_APPICONDIR, "inkscape.png", NULL);
617     if (Inkscape::IO::file_test(filename, (GFileTest)(G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK))) {
618         gtk_window_set_default_icon_from_file(filename, NULL);
619     }
620     g_free (filename);
621     filename = 0;
623     if (!sp_global_slideshow) {
624         gboolean create_new = TRUE;
626         /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
627         inkscape_application_init(argv[0], true);
629         while (fl) {
630             if (sp_file_open((gchar *)fl->data,NULL)) {
631                 create_new=FALSE;
632             }
633             fl = g_slist_remove(fl, fl->data);
634         }
635         if (create_new) {
636             sp_file_new_default();
637         }
638     } else {
639         if (fl) {
640             GtkWidget *ss;
641             /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
642             inkscape_application_init(argv[0], true);
643             ss = sp_slideshow_new(fl);
644             if (ss) gtk_widget_show(ss);
645         } else {
646             g_warning ("No slides to display");
647             exit(0);
648         }
649     }
651     main_instance.run();
653 #ifdef WIN32
654     //We might not need anything here
655     //sp_win32_finish(); <-- this is a NOP func
656 #endif
658     return 0;
661 int
662 sp_main_console(int argc, char const **argv)
664     /* We are started in text mode */
666     /* Do this g_type_init(), so that we can use Xft/Freetype2 (Pango)
667      * in a non-Gtk environment.  Used in libnrtype's
668      * FontInstance.cpp and FontFactory.cpp.
669      * http://mail.gnome.org/archives/gtk-list/2003-December/msg00063.html
670      */
671     g_type_init();
672     char **argv2 = const_cast<char **>(argv);
673     gtk_init_check( &argc, &argv2 );
674     //setlocale(LC_ALL, "");
676     GSList *fl = NULL;
677     int retVal = sp_common_main( argc, argv, &fl );
678     g_return_val_if_fail(retVal == 0, 1);
680     if (fl == NULL) {
681         g_print("Nothing to do!\n");
682         exit(0);
683     }
685     inkscape_application_init(argv[0], false);
687     while (fl) {
688         SPDocument *doc;
690         doc = Inkscape::Extension::open(NULL, (gchar *)fl->data);
691         if (doc == NULL) {
692             doc = Inkscape::Extension::open(Inkscape::Extension::db.get(SP_MODULE_KEY_INPUT_SVG), (gchar *)fl->data);
693         }
694         if (doc == NULL) {
695             g_warning("Specified document %s cannot be opened (is it valid SVG file?)", (gchar *) fl->data);
696         } else {
697             if (sp_vacuum_defs) {
698                 vacuum_document(doc);
699             }
700             if (sp_vacuum_defs && !sp_export_svg) {
701                 // save under the name given in the command line
702                 sp_repr_save_file(doc->rdoc, (gchar *)fl->data, SP_SVG_NS_URI);
703             }
704             if (sp_global_printer) {
705                 sp_print_document_to_file(doc, sp_global_printer);
706             }
707             if (sp_export_png || sp_export_id || sp_export_area_drawing) {
708                 sp_do_export_png(doc);
709             }
710             if (sp_export_svg) {
711                 Inkscape::XML::Document *rdoc;
712                 Inkscape::XML::Node *repr;
713                 rdoc = sp_repr_document_new("svg:svg");
714                 repr = rdoc->root();
715                 repr = sp_document_root(doc)->updateRepr(repr, SP_OBJECT_WRITE_BUILD);
716                 sp_repr_save_file(repr->document(), sp_export_svg, SP_SVG_NS_URI);
717             }
718             if (sp_export_ps) {
719                 do_export_ps(doc, sp_export_ps, "image/x-postscript");
720             }
721             if (sp_export_eps) {
722                 do_export_ps(doc, sp_export_eps, "image/x-e-postscript");
723             }
724             if (sp_export_pdf) {
725                 do_export_pdf(doc, sp_export_pdf, "application/pdf");
726             }
727             if (sp_query_width || sp_query_height) {
728                 do_query_dimension (doc, true, sp_query_width? NR::X : NR::Y, sp_query_id);
729             } else if (sp_query_x || sp_query_y) {
730                 do_query_dimension (doc, false, sp_query_x? NR::X : NR::Y, sp_query_id);
731             }
732         }
733         fl = g_slist_remove(fl, fl->data);
734     }
736     inkscape_unref();
738     return 0;
741 static void
742 do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gchar *id)
744     SPObject *o = NULL;
746     if (id) {
747         o = doc->getObjectById(id);
748         if (o) {
749             if (!SP_IS_ITEM (o)) {
750                 g_warning("Object with id=\"%s\" is not a visible item. Cannot query dimensions.", id);
751                 return;
752             }
753         } else {
754             g_warning("Object with id=\"%s\" is not found. Cannot query dimensions.", id);
755             return;
756         }
757     } else {
758         o = SP_DOCUMENT_ROOT(doc);
759     }
761     if (o) {
762         sp_document_ensure_up_to_date (doc);
763         SPItem *item = ((SPItem *) o);
764         NR::Rect area = item->invokeBbox(sp_item_i2doc_affine(item)); // "true" SVG bbox for scripting
766         Inkscape::SVGOStringStream os;
767         if (extent) {
768             os << area.extent(axis);
769         } else {
770             os << area.min()[axis];
771         }
772         g_print ("%s", os.str().c_str());
773     }
777 static void
778 sp_do_export_png(SPDocument *doc)
780     const gchar *filename = NULL;
781     gdouble dpi = 0.0;
783     if (sp_export_use_hints && (!sp_export_id && !sp_export_area_drawing)) {
784         g_warning ("--export-use-hints can only be used with --export-id or --export-area-drawing; ignored.");
785     }
787     GSList *items = NULL;
789     NRRect area;
790     if (sp_export_id || sp_export_area_drawing) {
792         SPObject *o = NULL;
793         SPObject *o_area = NULL;
794         if (sp_export_id && sp_export_area_drawing) {
795             o = doc->getObjectById(sp_export_id);
796             o_area = SP_DOCUMENT_ROOT (doc);
797         } else if (sp_export_id) {
798             o = doc->getObjectById(sp_export_id);
799             o_area = o;
800         } else if (sp_export_area_drawing) {
801             o = SP_DOCUMENT_ROOT (doc);
802             o_area = o;
803         } 
805         if (o) {
806             if (!SP_IS_ITEM (o)) {
807                 g_warning("Object with id=\"%s\" is not a visible item. Nothing exported.", sp_export_id);
808                 return;
809             }
811             items = g_slist_prepend (items, SP_ITEM(o));
813             if (sp_export_id_only) {
814                 g_print("Exporting only object with id=\"%s\"; all other objects hidden\n", sp_export_id);
815             }
817             if (sp_export_use_hints) {
819                 // retrieve export filename hint
820                 const gchar *fn_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-filename");
821                 if (fn_hint) {
822                     if (sp_export_png) {
823                         g_warning ("Using export filename from the command line (--export-png). Filename hint %s is ignored.", fn_hint);
824                         filename = sp_export_png;
825                     } else {
826                         filename = fn_hint;
827                     }
828                 } else {
829                     g_warning ("Export filename hint not found for the object.");
830                     filename = sp_export_png;
831                 }
833                 // retrieve export dpi hints
834                 const gchar *dpi_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-xdpi"); // only xdpi, ydpi is always the same now
835                 if (dpi_hint) {
836                     if (sp_export_dpi || sp_export_width || sp_export_height) {
837                         g_warning ("Using bitmap dimensions from the command line (--export-dpi, --export-width, or --export-height). DPI hint %s is ignored.", dpi_hint);
838                     } else {
839                         dpi = atof(dpi_hint);
840                     }
841                 } else {
842                     g_warning ("Export DPI hint not found for the object.");
843                 }
845             }
847             // write object bbox to area
848             sp_document_ensure_up_to_date (doc);
849             sp_item_invoke_bbox((SPItem *) o_area, &area, sp_item_i2r_affine((SPItem *) o_area), TRUE);
850         } else {
851             g_warning("Object with id=\"%s\" was not found in the document. Nothing exported.", sp_export_id);
852             return;
853         }
854     }
855     
856     if (sp_export_area) {
857         /* Try to parse area (given in SVG pixels) */
858         if (!sscanf(sp_export_area, "%lg:%lg:%lg:%lg", &area.x0, &area.y0, &area.x1, &area.y1) == 4) {
859             g_warning("Cannot parse export area '%s'; use 'x0:y0:x1:y1'. Nothing exported.", sp_export_area);
860             return;
861         }
862         if ((area.x0 >= area.x1) || (area.y0 >= area.y1)) {
863             g_warning("Export area '%s' has negative width or height. Nothing exported.", sp_export_area);
864             return;
865         }
866     } else if (sp_export_area_canvas || !(sp_export_id || sp_export_area_drawing)) {
867         /* Export the whole canvas */
868         sp_document_ensure_up_to_date (doc);
869         area.x0 = SP_ROOT(doc->root)->x.computed;
870         area.y0 = SP_ROOT(doc->root)->y.computed;
871         area.x1 = area.x0 + sp_document_width (doc);
872         area.y1 = area.y0 + sp_document_height (doc);
873     }
875     // set filename and dpi from options, if not yet set from the hints
876     if (!filename) {
877         if (!sp_export_png) {
878             g_warning ("No export filename given and no filename hint. Nothing exported.");
879             return;
880         }
881         filename = sp_export_png;
882     }
884     if (sp_export_dpi && dpi == 0.0) {
885         dpi = atof(sp_export_dpi);
886         if ((dpi < 0.1) || (dpi > 10000.0)) {
887             g_warning("DPI value %s out of range [0.1 - 10000.0]. Nothing exported.", sp_export_dpi);
888             return;
889         }
890         g_print("DPI: %g\n", dpi);
891     }
893     if (sp_export_area_snap) {
894         area.x0 = std::floor (area.x0);
895         area.y0 = std::floor (area.y0);
896         area.x1 = std::ceil (area.x1);
897         area.y1 = std::ceil (area.y1);
898     }
900     // default dpi
901     if (dpi == 0.0)
902         dpi = PX_PER_IN;
904     gint width = 0;
905     gint height = 0;
907     if (sp_export_width) {
908         width = atoi(sp_export_width);
909         if ((width < 1) || (width > 65536)) {
910             g_warning("Export width %d out of range (1 - 65536). Nothing exported.", width);
911             return;
912         }
913         dpi = (gdouble) width * PX_PER_IN / (area.x1 - area.x0);
914     }
916     if (sp_export_height) {
917         height = atoi(sp_export_height);
918         if ((height < 1) || (height > 65536)) {
919             g_warning("Export height %d out of range (1 - 65536). Nothing exported.", width);
920             return;
921         }
922         dpi = (gdouble) height * PX_PER_IN / (area.y1 - area.y0);
923     }
925     if (!sp_export_width) {
926         width = (gint) ((area.x1 - area.x0) * dpi / PX_PER_IN + 0.5);
927     }
929     if (!sp_export_height) {
930         height = (gint) ((area.y1 - area.y0) * dpi / PX_PER_IN + 0.5);
931     }
933     guint32 bgcolor = 0x00000000;
934     if (sp_export_background) {
935         // override the page color
936         bgcolor = sp_svg_read_color(sp_export_background, 0xffffff00);
937         bgcolor |= 0xff; // default is no opacity
938     } else {
939         // read from namedview
940         Inkscape::XML::Node *nv = sp_repr_lookup_name (doc->rroot, "sodipodi:namedview");
941         if (nv && nv->attribute("pagecolor"))
942             bgcolor = sp_svg_read_color(nv->attribute("pagecolor"), 0xffffff00);
943         if (nv && nv->attribute("inkscape:pageopacity"))
944             bgcolor |= SP_COLOR_F_TO_U(sp_repr_get_double_attribute (nv, "inkscape:pageopacity", 1.0));
945     }
947     if (sp_export_background_opacity) {
948         // override opacity
949         gfloat value;
950         if (sp_svg_number_read_f (sp_export_background_opacity, &value)) {
951             if (value > 1.0) {
952                 value = CLAMP (value, 1.0f, 255.0f);
953                 bgcolor &= (guint32) 0xffffff00;
954                 bgcolor |= (guint32) floor(value);
955             } else {
956                 value = CLAMP (value, 0.0f, 1.0f);
957                 bgcolor &= (guint32) 0xffffff00;
958                 bgcolor |= SP_COLOR_F_TO_U(value);
959             }
960         }
961     }
963     g_print("Background RRGGBBAA: %08x\n", bgcolor);
965     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);
967     g_print("Bitmap saved as: %s\n", filename);
969     if ((width >= 1) && (height >= 1) && (width < 65536) && (height < 65536)) {
970         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);
971     } else {
972         g_warning("Calculated bitmap dimensions %d %d are out of range (1 - 65535). Nothing exported.", width, height);
973     }
975     g_slist_free (items);
979 /**
980  *  Perform an export of either PS or EPS.
981  *
982  *  \param doc Document to export.
983  *  \param uri URI to export to.
984  *  \param mime MIME type to export as.
985  */
987 static void do_export_ps(SPDocument* doc, gchar const* uri, char const* mime)
989     Inkscape::Extension::DB::OutputList o;
990     Inkscape::Extension::db.get_output_list(o);
991     Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
992     while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
993         i++;
994     }
996     if (i == o.end())
997     {
998         g_warning ("Could not find an extension to export this file.");
999         return;
1000     }
1002     bool old_text_to_path = false;
1003     bool old_font_embedded = false;
1004     bool old_bbox_page = false;
1006     try {
1007         old_text_to_path = (*i)->get_param_bool("textToPath");
1008         (*i)->set_param_bool("textToPath", sp_export_text_to_path);
1009     }
1010     catch (...) {
1011         g_warning ("Could not set export-text-to-path option for this export.");
1012     }
1014     try {
1015         old_font_embedded = (*i)->get_param_bool("fontEmbedded");
1016         (*i)->set_param_bool("fontEmbedded", sp_export_font);
1017     }
1018     catch (...) {
1019         g_warning ("Could not set export-font option for this export.");
1020     }
1022     try {
1023         old_bbox_page = (*i)->get_param_bool("pageBoundingBox");
1024         (*i)->set_param_bool("pageBoundingBox", sp_export_bbox_page);
1025     }
1026     catch (...) {
1027         g_warning ("Could not set export-bbox-page option for this export.");
1028     }
1030     (*i)->save(doc, uri);
1032     try {
1033         (*i)->set_param_bool("textToPath", old_text_to_path);
1034         (*i)->set_param_bool("fontEmbedded", old_font_embedded);
1035         (*i)->set_param_bool("pageBoundingBox", old_bbox_page);
1036     }
1037     catch (...) {
1039     }
1042 /**
1043  *  Perform a PDF export
1044  *
1045  *  \param doc Document to export.
1046  *  \param uri URI to export to.
1047  *  \param mime MIME type to export as.
1048  */
1050 static void do_export_pdf(SPDocument* doc, gchar const* uri, char const* mime)
1052     Inkscape::Extension::DB::OutputList o;
1053     Inkscape::Extension::db.get_output_list(o);
1054     Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
1055     while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
1056         i++;
1057     }
1059     if (i == o.end())
1060     {
1061         g_warning ("Could not find an extension to export this file.");
1062         return;
1063     }
1065     (*i)->save(doc, uri);
1068 #ifdef WIN32
1069 bool replaceArgs( int& argc, char**& argv )
1071     bool worked = false;
1073 #ifdef REPLACEARGS_DEBUG
1074     MessageBoxA( NULL, "GetCommandLineW() getting called", "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1075 #endif // REPLACEARGS_DEBUG
1077     wchar_t* line = GetCommandLineW();
1078     if ( line )
1079     {
1080 #ifdef REPLACEARGS_DEBUG
1081         {
1082             gchar* utf8Line = g_utf16_to_utf8( (gunichar2*)line, -1, NULL, NULL, NULL );
1083             if ( utf8Line )
1084             {
1085                 gchar *safe = Inkscape::IO::sanitizeString(utf8Line);
1086                 {
1087                     char tmp[strlen(safe) + 32];
1088                     snprintf( tmp, sizeof(tmp), "GetCommandLineW() = '%s'", safe );
1089                     MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1090                 }
1091             }
1092         }
1093 #endif // REPLACEARGS_DEBUG
1095         int numArgs = 0;
1096         wchar_t** parsed = CommandLineToArgvW( line, &numArgs );
1098 #ifdef REPLACEARGS_ANSI
1099 // test code for trying things on Win95/98/ME
1100         if ( !parsed )
1101         {
1102 #ifdef REPLACEARGS_DEBUG
1103             MessageBoxA( NULL, "Unable to process command-line. Faking it", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1104 #endif // REPLACEARGS_DEBUG
1105             int lineLen = wcslen(line) + 1;
1106             wchar_t* lineDup = new wchar_t[lineLen];
1107             wcsncpy( lineDup, line, lineLen );
1109             int pos = 0;
1110             bool inQuotes = false;
1111             bool inWhitespace = true;
1112             std::vector<int> places;
1113             while ( lineDup[pos] )
1114             {
1115                 if ( inQuotes )
1116                 {
1117                     if ( lineDup[pos] == L'"' )
1118                     {
1119                         inQuotes = false;
1120                     }
1121                 }
1122                 else if ( lineDup[pos] == L'"' )
1123                 {
1124                     inQuotes = true;
1125                     inWhitespace = false;
1126                     places.push_back(pos);
1127                 }
1128                 else if ( lineDup[pos] == L' ' || lineDup[pos] == L'\t' )
1129                 {
1130                     if ( !inWhitespace )
1131                     {
1132                         inWhitespace = true;
1133                         lineDup[pos] = 0;
1134                     }
1135                 }
1136                 else if ( inWhitespace && (lineDup[pos] != L' ' && lineDup[pos] != L'\t') )
1137                 {
1138                     inWhitespace = false;
1139                     places.push_back(pos);
1140                 }
1141                 else
1142                 {
1143                     // consume
1144                 }
1145                 pos++;
1146             }
1147 #ifdef REPLACEARGS_DEBUG
1148             {
1149                 char tmp[256];
1150                 snprintf( tmp, sizeof(tmp), "Counted %d args", places.size() );
1151                 MessageBoxA( NULL, tmp, "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1152             }
1153 #endif // REPLACEARGS_DEBUG
1155             wchar_t** block = new wchar_t*[places.size()];
1156             int i = 0;
1157             for ( std::vector<int>::iterator it = places.begin(); it != places.end(); it++ )
1158             {
1159                 block[i++] = &lineDup[*it];
1160             }
1161             parsed = block;
1162             numArgs = places.size();
1163         }
1164 #endif // REPLACEARGS_ANSI
1166         if ( parsed )
1167         {
1168             std::vector<wchar_t*>expandedArgs;
1169             if ( numArgs > 0 )
1170             {
1171                 expandedArgs.push_back( parsed[0] );
1172             }
1174             for ( int i1 = 1; i1 < numArgs; i1++ )
1175             {
1176                 bool wildcarded = (wcschr(parsed[i1], L'?') != NULL) || (wcschr(parsed[i1], L'*') != NULL);
1177                 wildcarded &= parsed[i1][0] != L'"';
1178                 wildcarded &= parsed[i1][0] != L'-';
1179                 if ( wildcarded )
1180                 {
1181 #ifdef REPLACEARGS_ANSI
1182                     WIN32_FIND_DATAA data = {0};
1183 #else
1184                     WIN32_FIND_DATAW data = {0};
1185 #endif // REPLACEARGS_ANSI
1187                     int baseLen = wcslen(parsed[i1]) + 2;
1188                     wchar_t* base = new wchar_t[baseLen];
1189                     wcsncpy( base, parsed[i1], baseLen );
1190                     wchar_t* last = wcsrchr( base, L'\\' );
1191                     if ( last )
1192                     {
1193                         last[1] = 0;
1194                     }
1195                     else
1196                     {
1197                         base[0] = 0;
1198                     }
1199                     baseLen = wcslen( base );
1201 #ifdef REPLACEARGS_ANSI
1202                     char target[MAX_PATH];
1203                     if ( WideCharToMultiByte( CP_ACP, 0, parsed[i1], -1, target, sizeof(target), NULL, NULL) )
1204                     {
1205                         HANDLE hf = FindFirstFileA( target, &data );
1206 #else
1207                         HANDLE hf = FindFirstFileW( parsed[i1], &data );
1208 #endif // REPLACEARGS_ANSI
1209                         if ( hf != INVALID_HANDLE_VALUE )
1210                         {
1211                             BOOL found = TRUE;
1212                             do
1213                             {
1214 #ifdef REPLACEARGS_ANSI
1215                                 int howMany = MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, NULL, 0 );
1216                                 if ( howMany > 0 )
1217                                 {
1218                                     howMany += baseLen;
1219                                     wchar_t* tmp = new wchar_t[howMany + 1];
1220                                     wcsncpy( tmp, base, howMany + 1 );
1221                                     MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, tmp + baseLen, howMany + 1 - baseLen );
1222                                     expandedArgs.push_back( tmp );
1223                                     found = FindNextFileA( hf, &data );
1224                                 }
1225 #else
1226                                 int howMany = wcslen(data.cFileName) + baseLen;
1227                                 wchar_t* tmp = new wchar_t[howMany + 1];
1228                                 wcsncpy( tmp, base, howMany + 1 );
1229                                 wcsncat( tmp, data.cFileName, howMany + 1 );
1230                                 expandedArgs.push_back( tmp );
1231                                 found = FindNextFileW( hf, &data );
1232 #endif // REPLACEARGS_ANSI
1233                             } while ( found );
1235                             FindClose( hf );
1236                         }
1237                         else
1238                         {
1239                             expandedArgs.push_back( parsed[i1] );
1240                         }
1241 #ifdef REPLACEARGS_ANSI
1242                     }
1243 #endif // REPLACEARGS_ANSI
1245                     delete[] base;
1246                 }
1247                 else
1248                 {
1249                     expandedArgs.push_back( parsed[i1] );
1250                 }
1251             }
1253             {
1254                 wchar_t** block = new wchar_t*[expandedArgs.size()];
1255                 int iz = 0;
1256                 for ( std::vector<wchar_t*>::iterator it = expandedArgs.begin(); it != expandedArgs.end(); it++ )
1257                 {
1258                     block[iz++] = *it;
1259                 }
1260                 parsed = block;
1261                 numArgs = expandedArgs.size();
1262             }
1264             std::vector<gchar*> newArgs;
1265             for ( int i = 0; i < numArgs; i++ )
1266             {
1267                 gchar* replacement = g_utf16_to_utf8( (gunichar2*)parsed[i], -1, NULL, NULL, NULL );
1268                 if ( replacement )
1269                 {
1270 #ifdef REPLACEARGS_DEBUG
1271                     gchar *safe2 = Inkscape::IO::sanitizeString(replacement);
1273                     if ( safe2 )
1274                     {
1275                         {
1276                             char tmp[1024];
1277                             snprintf( tmp, sizeof(tmp), "    [%2d] = '%s'", i, safe2 );
1278                             MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1279                         }
1280                         g_free( safe2 );
1281                     }
1282 #endif // REPLACEARGS_DEBUG
1284                     newArgs.push_back( replacement );
1285                 }
1286                 else
1287                 {
1288                     newArgs.push_back( blankParam );
1289                 }
1290             }
1292             // Now push our munged params to be the new argv and argc
1293             {
1294                 char** block = new char*[newArgs.size()];
1295                 int iz = 0;
1296                 for ( std::vector<char*>::iterator it = newArgs.begin(); it != newArgs.end(); it++ )
1297                 {
1298                     block[iz++] = *it;
1299                 }
1300                 argv = block;
1301                 argc = newArgs.size();
1302                 worked = true;
1303             }
1304         }
1305 #ifdef REPLACEARGS_DEBUG
1306         else
1307         {
1308             MessageBoxA( NULL, "Unable to process command-line", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1309         }
1310 #endif // REPLACEARGS_DEBUG
1311     }
1312 #ifdef REPLACEARGS_DEBUG
1313     else
1314     {
1315         {
1316             MessageBoxA( NULL,  "Unable to fetch result from GetCommandLineW()", "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1317         }
1319         char* line2 = GetCommandLineA();
1320         if ( line2 )
1321         {
1322             gchar *safe = Inkscape::IO::sanitizeString(line2);
1323             {
1324                 {
1325                     char tmp[strlen(safe) + 32];
1326                     snprintf( tmp, sizeof(tmp), "GetCommandLineA() = '%s'", safe );
1327                     MessageBoxA( NULL, tmp, "GetCommandLineA", MB_OK | MB_ICONINFORMATION );
1328                 }
1329             }
1330         }
1331         else
1332         {
1333             MessageBoxA( NULL, "Unable to fetch result from GetCommandLineA()", "GetCommandLineA", MB_OK | MB_ICONINFORMATION );
1334         }
1335     }
1336 #endif // REPLACEARGS_DEBUG
1338     return worked;
1340 #endif // WIN32
1342 static GSList *
1343 sp_process_args(poptContext ctx)
1345     GSList *fl = NULL;
1347     gint a;
1348     while ((a = poptGetNextOpt(ctx)) >= 0) {
1349         switch (a) {
1350             case SP_ARG_FILE: {
1351                 gchar const *fn = poptGetOptArg(ctx);
1352                 if (fn != NULL) {
1353                     fl = g_slist_append(fl, g_strdup(fn));
1354                 }
1355                 break;
1356             }
1357             case SP_ARG_VERSION: {
1358                 printf("Inkscape %s (%s)\n", INKSCAPE_VERSION, __DATE__);
1359                 exit(0);
1360                 break;
1361             }
1362             case SP_ARG_EXTENSIONDIR: {
1363                 printf("%s\n", INKSCAPE_EXTENSIONDIR);
1364                 exit(0);
1365                 break;
1366             }
1367             default: {
1368                 break;
1369             }
1370         }
1371     }
1373     gchar const ** const args = poptGetArgs(ctx);
1374     if (args != NULL) {
1375         for (unsigned i = 0; args[i] != NULL; i++) {
1376             fl = g_slist_append(fl, g_strdup(args[i]));
1377         }
1378     }
1380     return fl;
1384 /*
1385   Local Variables:
1386   mode:c++
1387   c-file-style:"stroustrup"
1388   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
1389   indent-tabs-mode:nil
1390   fill-column:99
1391   End:
1392 */
1393 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :