Code

added include of "helper/png-write.h" to fix compile error:
[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 <gtk/gtkmain.h>
53 #include "gc-core.h"
55 #include "macros.h"
56 #include "file.h"
57 #include "document.h"
58 #include "sp-object.h"
59 #include "interface.h"
60 #include "print.h"
61 #include "slideshow.h"
62 #include "color.h"
63 #include "sp-item.h"
64 #include "sp-root.h"
65 #include "unit-constants.h"
67 #include "svg/svg.h"
68 #include "svg/svg-color.h"
69 #include "svg/stringstream.h"
71 #include "inkscape-private.h"
72 #include "inkscape-stock.h"
73 #include "inkscape_version.h"
75 #include "sp-namedview.h"
76 #include "sp-guide.h"
77 #include "sp-object-repr.h"
78 #include "xml/repr.h"
80 #include "io/sys.h"
82 #include "debug/logger.h"
84 //#include "helper/png-write.h"
86 #include <extension/extension.h>
87 #include <extension/system.h>
88 #include <extension/db.h>
89 #include <extension/output.h>
91 #ifdef WIN32
92 //#define REPLACEARGS_ANSI
93 //#define REPLACEARGS_DEBUG
95 #include "registrytool.h"
97 #include "extension/internal/win32.h"
98 using Inkscape::Extension::Internal::PrintWin32;
100 #endif // WIN32
102 #include "extension/init.h"
104 #include <glibmm/i18n.h>
105 #include <gtkmm/main.h>
107 #ifndef HAVE_BIND_TEXTDOMAIN_CODESET
108 #define bind_textdomain_codeset(p,c)
109 #endif
111 #include "application/application.h"
113 enum {
114     SP_ARG_NONE,
115     SP_ARG_NOGUI,
116     SP_ARG_GUI,
117     SP_ARG_FILE,
118     SP_ARG_PRINT,
119     SP_ARG_EXPORT_PNG,
120     SP_ARG_EXPORT_DPI,
121     SP_ARG_EXPORT_AREA,
122     SP_ARG_EXPORT_AREA_DRAWING,
123     SP_ARG_EXPORT_AREA_CANVAS,
124     SP_ARG_EXPORT_AREA_SNAP,
125     SP_ARG_EXPORT_WIDTH,
126     SP_ARG_EXPORT_HEIGHT,
127     SP_ARG_EXPORT_ID,
128     SP_ARG_EXPORT_ID_ONLY,
129     SP_ARG_EXPORT_USE_HINTS,
130     SP_ARG_EXPORT_BACKGROUND,
131     SP_ARG_EXPORT_BACKGROUND_OPACITY,
132     SP_ARG_EXPORT_SVG,
133     SP_ARG_EXPORT_PS,
134     SP_ARG_EXPORT_EPS,
135     SP_ARG_EXPORT_PDF,
136     SP_ARG_EXPORT_TEXT_TO_PATH,
137     SP_ARG_EXPORT_BBOX_PAGE,
138     SP_ARG_EXTENSIONDIR,
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_NEW_GUI,
147     SP_ARG_VACUUM_DEFS,
148     SP_ARG_LAST
149 };
151 int sp_main_gui(int argc, char const **argv);
152 int sp_main_console(int argc, char const **argv);
153 static void sp_do_export_png(SPDocument *doc);
154 static void do_export_ps(SPDocument* doc, gchar const* uri, char const *mime);
155 static void do_export_pdf(SPDocument* doc, gchar const* uri, char const *mime);
156 static void do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gchar *id);
159 static gchar *sp_global_printer = NULL;
160 static gboolean sp_global_slideshow = FALSE;
161 static gchar *sp_export_png = NULL;
162 static gchar *sp_export_dpi = NULL;
163 static gchar *sp_export_area = NULL;
164 static gboolean sp_export_area_drawing = FALSE;
165 static gboolean sp_export_area_canvas = FALSE;
166 static gchar *sp_export_width = NULL;
167 static gchar *sp_export_height = NULL;
168 static gchar *sp_export_id = NULL;
169 static gchar *sp_export_background = NULL;
170 static gchar *sp_export_background_opacity = NULL;
171 static gboolean sp_export_area_snap = FALSE;
172 static gboolean sp_export_use_hints = FALSE;
173 static gboolean sp_export_id_only = FALSE;
174 static gchar *sp_export_svg = NULL;
175 static gchar *sp_export_ps = NULL;
176 static gchar *sp_export_eps = NULL;
177 static gchar *sp_export_pdf = NULL;
178 static gboolean sp_export_text_to_path = 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-bbox-page", 'B',
315      POPT_ARG_NONE, &sp_export_bbox_page, SP_ARG_EXPORT_BBOX_PAGE,
316      N_("Export files with the bounding box set to the page size (EPS)"),
317      NULL},
319     {"query-x", 'X',
320      POPT_ARG_NONE, &sp_query_x, SP_ARG_QUERY_X,
321      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
322      N_("Query the X coordinate of the drawing or, if specified, of the object with --query-id"),
323      NULL},
325     {"query-y", 'Y',
326      POPT_ARG_NONE, &sp_query_y, SP_ARG_QUERY_Y,
327      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
328      N_("Query the Y coordinate of the drawing or, if specified, of the object with --query-id"),
329      NULL},
331     {"query-width", 'W',
332      POPT_ARG_NONE, &sp_query_width, SP_ARG_QUERY_WIDTH,
333      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
334      N_("Query the width of the drawing or, if specified, of the object with --query-id"),
335      NULL},
337     {"query-height", 'H',
338      POPT_ARG_NONE, &sp_query_height, SP_ARG_QUERY_HEIGHT,
339      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
340      N_("Query the height of the drawing or, if specified, of the object with --query-id"),
341      NULL},
343     {"query-id", 'I',
344      POPT_ARG_STRING, &sp_query_id, SP_ARG_QUERY_ID,
345      N_("The ID of the object whose dimensions are queried"),
346      N_("ID")},
348     {"extension-directory", 'x',
349      POPT_ARG_NONE, NULL, SP_ARG_EXTENSIONDIR,
350      // TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory
351      N_("Print out the extension directory and exit"),
352      NULL},
354     {"slideshow", 's',
355      POPT_ARG_NONE, &sp_global_slideshow, SP_ARG_SLIDESHOW,
356      N_("Show given files one-by-one, switch to next on any key/mouse event"),
357      NULL},
359     {"new-gui", 'G',
360      POPT_ARG_NONE, &sp_new_gui, SP_ARG_NEW_GUI,
361      N_("Use the new Gtkmm GUI interface"),
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         } else if (!strcmp(argv[i], "-G") || !strcmp(argv[i], "--new-gui")) {
471             sp_new_gui = TRUE;
472             break;
473         }
474     }
476 #ifdef WIN32
477 #ifndef REPLACEARGS_ANSI
478     if ( PrintWin32::is_os_wide() )
479 #endif // REPLACEARGS_ANSI
480     {
481         // If the call fails, we'll need to convert charsets
482         needToRecodeParams = !replaceArgs( argc, argv );
483     }
484 #endif // WIN32
486     /// \todo  Should this be a static object (see inkscape.cpp)?
487     Inkscape::NSApplication::Application app(argc, argv, use_gui, sp_new_gui);
489     return app.run();
492 void fixupSingleFilename( gchar **orig, gchar **spare )
494     if ( orig && *orig && **orig ) {
495         GError *error = NULL;
496         gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(*orig, -1, NULL, NULL, &error);
497         if ( newFileName )
498         {
499             *orig = newFileName;
500             if ( spare ) {
501                 *spare = newFileName;
502             }
503 //             g_message("Set a replacement fixup");
504         }
505     }
508 GSList *fixupFilenameEncoding( GSList* fl )
510     GSList *newFl = NULL;
511     while ( fl ) {
512         gchar *fn = static_cast<gchar*>(fl->data);
513         fl = g_slist_remove( fl, fl->data );
514         gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(fn, -1, NULL, NULL, NULL);
515         if ( newFileName ) {
517             if ( 0 )
518             {
519                 gchar *safeFn = Inkscape::IO::sanitizeString(fn);
520                 gchar *safeNewFn = Inkscape::IO::sanitizeString(newFileName);
521                 GtkWidget *w = gtk_message_dialog_new( NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
522                                                        "Note: Converted '%s' to '%s'", safeFn, safeNewFn );
523                 gtk_dialog_run (GTK_DIALOG (w));
524                 gtk_widget_destroy (w);
525                 g_free(safeNewFn);
526                 g_free(safeFn);
527             }
529             g_free( fn );
530             fn = newFileName;
531             newFileName = 0;
532         }
533         else
534             if ( 0 )
535         {
536             gchar *safeFn = Inkscape::IO::sanitizeString(fn);
537             GtkWidget *w = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "Error: Unable to convert '%s'", safeFn );
538             gtk_dialog_run (GTK_DIALOG (w));
539             gtk_widget_destroy (w);
540             g_free(safeFn);
541         }
542         newFl = g_slist_append( newFl, fn );
543     }
544     return newFl;
547 int sp_common_main( int argc, char const **argv, GSList **flDest )
549     /// \todo fixme: Move these to some centralized location (Lauris)
550     sp_object_type_register("sodipodi:namedview", SP_TYPE_NAMEDVIEW);
551     sp_object_type_register("sodipodi:guide", SP_TYPE_GUIDE);
554     // temporarily switch gettext encoding to locale, so that help messages can be output properly
555     gchar const *charset;
556     g_get_charset(&charset);
558     bind_textdomain_codeset(GETTEXT_PACKAGE, charset);
560     poptContext ctx = poptGetContext(NULL, argc, argv, options, 0);
561     poptSetOtherOptionHelp(ctx, _("[OPTIONS...] [FILE...]\n\nAvailable options:"));
562     g_return_val_if_fail(ctx != NULL, 1);
564     /* Collect own arguments */
565     GSList *fl = sp_process_args(ctx);
566     poptFreeContext(ctx);
568     // now switch gettext back to UTF-8 (for GUI)
569     bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
571     // Now let's see if the file list still holds up
572     if ( needToRecodeParams )
573     {
574         fl = fixupFilenameEncoding( fl );
575     }
577     // Check the globals for filename-fixup
578     if ( needToRecodeParams )
579     {
580         fixupSingleFilename( &sp_export_png, &sp_export_png_utf8 );
581         fixupSingleFilename( &sp_export_svg, &sp_export_svg_utf8 );
582         fixupSingleFilename( &sp_global_printer, &sp_global_printer_utf8 );
583     }
584     else
585     {
586         if ( sp_export_png )
587             sp_export_png_utf8 = g_strdup( sp_export_png );
588         if ( sp_export_svg )
589             sp_export_svg_utf8 = g_strdup( sp_export_svg );
590         if ( sp_global_printer )
591             sp_global_printer_utf8 = g_strdup( sp_global_printer );
592     }
594     // Return the list if wanted, else free it up.
595     if ( flDest ) {
596         *flDest = fl;
597         fl = 0;
598     } else {
599         while ( fl ) {
600             g_free( fl->data );
601             fl = g_slist_remove( fl, fl->data );
602         }
603     }
604     return 0;
607 int
608 sp_main_gui(int argc, char const **argv)
610     Gtk::Main main_instance (&argc, const_cast<char ***>(&argv));
612     GSList *fl = NULL;
613     int retVal = sp_common_main( argc, argv, &fl );
614     g_return_val_if_fail(retVal == 0, 1);
616     inkscape_gtk_stock_init();
618     /* Set default icon */
619     gchar *filename = (gchar *) g_build_filename (INKSCAPE_APPICONDIR, "inkscape.png", NULL);
620     if (Inkscape::IO::file_test(filename, (GFileTest)(G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK))) {
621         gtk_window_set_default_icon_from_file(filename, NULL);
622     }
623     g_free (filename);
624     filename = 0;
626     if (!sp_global_slideshow) {
627         gboolean create_new = TRUE;
629         /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
630         inkscape_application_init(argv[0], true);
632         while (fl) {
633             if (sp_file_open((gchar *)fl->data,NULL)) {
634                 create_new=FALSE;
635             }
636             fl = g_slist_remove(fl, fl->data);
637         }
638         if (create_new) {
639             sp_file_new_default();
640         }
641     } else {
642         if (fl) {
643             GtkWidget *ss;
644             /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
645             inkscape_application_init(argv[0], true);
646             ss = sp_slideshow_new(fl);
647             if (ss) gtk_widget_show(ss);
648         } else {
649             g_warning ("No slides to display");
650             exit(0);
651         }
652     }
654     main_instance.run();
656 #ifdef WIN32
657     //We might not need anything here
658     //sp_win32_finish(); <-- this is a NOP func
659 #endif
661     return 0;
664 int
665 sp_main_console(int argc, char const **argv)
667     /* We are started in text mode */
669     /* Do this g_type_init(), so that we can use Xft/Freetype2 (Pango)
670      * in a non-Gtk environment.  Used in libnrtype's
671      * FontInstance.cpp and FontFactory.cpp.
672      * http://mail.gnome.org/archives/gtk-list/2003-December/msg00063.html
673      */
674     g_type_init();
675     char **argv2 = const_cast<char **>(argv);
676     gtk_init_check( &argc, &argv2 );
677     //setlocale(LC_ALL, "");
679     GSList *fl = NULL;
680     int retVal = sp_common_main( argc, argv, &fl );
681     g_return_val_if_fail(retVal == 0, 1);
683     if (fl == NULL) {
684         g_print("Nothing to do!\n");
685         exit(0);
686     }
688     inkscape_application_init(argv[0], false);
690     while (fl) {
691         SPDocument *doc;
693         doc = Inkscape::Extension::open(NULL, (gchar *)fl->data);
694         if (doc == NULL) {
695             doc = Inkscape::Extension::open(Inkscape::Extension::db.get(SP_MODULE_KEY_INPUT_SVG), (gchar *)fl->data);
696         }
697         if (doc == NULL) {
698             g_warning("Specified document %s cannot be opened (is it valid SVG file?)", (gchar *) fl->data);
699         } else {
700             if (sp_vacuum_defs) {
701                 vacuum_document(doc);
702             }
703             if (sp_vacuum_defs && !sp_export_svg) {
704                 // save under the name given in the command line
705                 sp_repr_save_file(doc->rdoc, (gchar *)fl->data, SP_SVG_NS_URI);
706             }
707             if (sp_global_printer) {
708                 sp_print_document_to_file(doc, sp_global_printer);
709             }
710             if (sp_export_png || sp_export_id || sp_export_area_drawing) {
711                 sp_do_export_png(doc);
712             }
713             if (sp_export_svg) {
714                 Inkscape::XML::Document *rdoc;
715                 Inkscape::XML::Node *repr;
716                 rdoc = sp_repr_document_new("svg:svg");
717                 repr = rdoc->root();
718                 repr = sp_document_root(doc)->updateRepr(repr, SP_OBJECT_WRITE_BUILD);
719                 sp_repr_save_file(repr->document(), sp_export_svg, SP_SVG_NS_URI);
720             }
721             if (sp_export_ps) {
722                 do_export_ps(doc, sp_export_ps, "image/x-postscript");
723             }
724             if (sp_export_eps) {
725                 do_export_ps(doc, sp_export_eps, "image/x-e-postscript");
726             }
727             if (sp_export_pdf) {
728                 do_export_pdf(doc, sp_export_pdf, "application/pdf");
729             }
730             if (sp_query_width || sp_query_height) {
731                 do_query_dimension (doc, true, sp_query_width? NR::X : NR::Y, sp_query_id);
732             } else if (sp_query_x || sp_query_y) {
733                 do_query_dimension (doc, false, sp_query_x? NR::X : NR::Y, sp_query_id);
734             }
735         }
736         fl = g_slist_remove(fl, fl->data);
737     }
739     inkscape_unref();
741     return 0;
744 static void
745 do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gchar *id)
747     SPObject *o = NULL;
749     if (id) {
750         o = doc->getObjectById(id);
751         if (o) {
752             if (!SP_IS_ITEM (o)) {
753                 g_warning("Object with id=\"%s\" is not a visible item. Cannot query dimensions.", id);
754                 return;
755             }
756         } else {
757             g_warning("Object with id=\"%s\" is not found. Cannot query dimensions.", id);
758             return;
759         }
760     } else {
761         o = SP_DOCUMENT_ROOT(doc);
762     }
764     if (o) {
765         sp_document_ensure_up_to_date (doc);
766         SPItem *item = ((SPItem *) o);
767         NR::Rect area = item->invokeBbox(sp_item_i2doc_affine(item)); // "true" SVG bbox for scripting
769         Inkscape::SVGOStringStream os;
770         if (extent) {
771             os << area.extent(axis);
772         } else {
773             os << area.min()[axis];
774         }
775         g_print ("%s", os.str().c_str());
776     }
780 static void
781 sp_do_export_png(SPDocument *doc)
783     const gchar *filename = NULL;
784     gdouble dpi = 0.0;
786     if (sp_export_use_hints && (!sp_export_id && !sp_export_area_drawing)) {
787         g_warning ("--export-use-hints can only be used with --export-id or --export-area-drawing; ignored.");
788     }
790     GSList *items = NULL;
792     NRRect area;
793     if (sp_export_id || sp_export_area_drawing) {
795         SPObject *o = NULL;
796         SPObject *o_area = NULL;
797         if (sp_export_id && sp_export_area_drawing) {
798             o = doc->getObjectById(sp_export_id);
799             o_area = SP_DOCUMENT_ROOT (doc);
800         } else if (sp_export_id) {
801             o = doc->getObjectById(sp_export_id);
802             o_area = o;
803         } else if (sp_export_area_drawing) {
804             o = SP_DOCUMENT_ROOT (doc);
805             o_area = o;
806         } 
808         if (o) {
809             if (!SP_IS_ITEM (o)) {
810                 g_warning("Object with id=\"%s\" is not a visible item. Nothing exported.", sp_export_id);
811                 return;
812             }
814             items = g_slist_prepend (items, SP_ITEM(o));
816             if (sp_export_id_only) {
817                 g_print("Exporting only object with id=\"%s\"; all other objects hidden\n", sp_export_id);
818             }
820             if (sp_export_use_hints) {
822                 // retrieve export filename hint
823                 const gchar *fn_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-filename");
824                 if (fn_hint) {
825                     if (sp_export_png) {
826                         g_warning ("Using export filename from the command line (--export-png). Filename hint %s is ignored.", fn_hint);
827                         filename = sp_export_png;
828                     } else {
829                         filename = fn_hint;
830                     }
831                 } else {
832                     g_warning ("Export filename hint not found for the object.");
833                     filename = sp_export_png;
834                 }
836                 // retrieve export dpi hints
837                 const gchar *dpi_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-xdpi"); // only xdpi, ydpi is always the same now
838                 if (dpi_hint) {
839                     if (sp_export_dpi || sp_export_width || sp_export_height) {
840                         g_warning ("Using bitmap dimensions from the command line (--export-dpi, --export-width, or --export-height). DPI hint %s is ignored.", dpi_hint);
841                     } else {
842                         dpi = atof(dpi_hint);
843                     }
844                 } else {
845                     g_warning ("Export DPI hint not found for the object.");
846                 }
848             }
850             // write object bbox to area
851             sp_document_ensure_up_to_date (doc);
852             sp_item_invoke_bbox((SPItem *) o_area, &area, sp_item_i2r_affine((SPItem *) o_area), TRUE);
853         } else {
854             g_warning("Object with id=\"%s\" was not found in the document. Nothing exported.", sp_export_id);
855             return;
856         }
857     }
858     
859     if (sp_export_area) {
860         /* Try to parse area (given in SVG pixels) */
861         if (!sscanf(sp_export_area, "%lg:%lg:%lg:%lg", &area.x0, &area.y0, &area.x1, &area.y1) == 4) {
862             g_warning("Cannot parse export area '%s'; use 'x0:y0:x1:y1'. Nothing exported.", sp_export_area);
863             return;
864         }
865         if ((area.x0 >= area.x1) || (area.y0 >= area.y1)) {
866             g_warning("Export area '%s' has negative width or height. Nothing exported.", sp_export_area);
867             return;
868         }
869     } else if (sp_export_area_canvas || !(sp_export_id || sp_export_area_drawing)) {
870         /* Export the whole canvas */
871         sp_document_ensure_up_to_date (doc);
872         area.x0 = SP_ROOT(doc->root)->x.computed;
873         area.y0 = SP_ROOT(doc->root)->y.computed;
874         area.x1 = area.x0 + sp_document_width (doc);
875         area.y1 = area.y0 + sp_document_height (doc);
876     }
878     // set filename and dpi from options, if not yet set from the hints
879     if (!filename) {
880         if (!sp_export_png) {
881             g_warning ("No export filename given and no filename hint. Nothing exported.");
882             return;
883         }
884         filename = sp_export_png;
885     }
887     if (sp_export_dpi && dpi == 0.0) {
888         dpi = atof(sp_export_dpi);
889         if ((dpi < 0.1) || (dpi > 10000.0)) {
890             g_warning("DPI value %s out of range [0.1 - 10000.0]. Nothing exported.", sp_export_dpi);
891             return;
892         }
893         g_print("DPI: %g\n", dpi);
894     }
896     if (sp_export_area_snap) {
897         area.x0 = std::floor (area.x0);
898         area.y0 = std::floor (area.y0);
899         area.x1 = std::ceil (area.x1);
900         area.y1 = std::ceil (area.y1);
901     }
903     // default dpi
904     if (dpi == 0.0)
905         dpi = PX_PER_IN;
907     gint width = 0;
908     gint height = 0;
910     if (sp_export_width) {
911         width = atoi(sp_export_width);
912         if ((width < 1) || (width > 65536)) {
913             g_warning("Export width %d out of range (1 - 65536). Nothing exported.", width);
914             return;
915         }
916         dpi = (gdouble) width * PX_PER_IN / (area.x1 - area.x0);
917     }
919     if (sp_export_height) {
920         height = atoi(sp_export_height);
921         if ((height < 1) || (height > 65536)) {
922             g_warning("Export height %d out of range (1 - 65536). Nothing exported.", width);
923             return;
924         }
925         dpi = (gdouble) height * PX_PER_IN / (area.y1 - area.y0);
926     }
928     if (!sp_export_width) {
929         width = (gint) ((area.x1 - area.x0) * dpi / PX_PER_IN + 0.5);
930     }
932     if (!sp_export_height) {
933         height = (gint) ((area.y1 - area.y0) * dpi / PX_PER_IN + 0.5);
934     }
936     guint32 bgcolor = 0x00000000;
937     if (sp_export_background) {
938         // override the page color
939         bgcolor = sp_svg_read_color(sp_export_background, 0xffffff00);
940         bgcolor |= 0xff; // default is no opacity
941     } else {
942         // read from namedview
943         Inkscape::XML::Node *nv = sp_repr_lookup_name (doc->rroot, "sodipodi:namedview");
944         if (nv && nv->attribute("pagecolor"))
945             bgcolor = sp_svg_read_color(nv->attribute("pagecolor"), 0xffffff00);
946         if (nv && nv->attribute("inkscape:pageopacity"))
947             bgcolor |= SP_COLOR_F_TO_U(sp_repr_get_double_attribute (nv, "inkscape:pageopacity", 1.0));
948     }
950     if (sp_export_background_opacity) {
951         // override opacity
952         gfloat value;
953         if (sp_svg_number_read_f (sp_export_background_opacity, &value)) {
954             if (value > 1.0) {
955                 value = CLAMP (value, 1.0f, 255.0f);
956                 bgcolor &= (guint32) 0xffffff00;
957                 bgcolor |= (guint32) floor(value);
958             } else {
959                 value = CLAMP (value, 0.0f, 1.0f);
960                 bgcolor &= (guint32) 0xffffff00;
961                 bgcolor |= SP_COLOR_F_TO_U(value);
962             }
963         }
964     }
966     g_print("Background RRGGBBAA: %08x\n", bgcolor);
968     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);
970     g_print("Bitmap saved as: %s\n", filename);
972     if ((width >= 1) && (height >= 1) && (width < 65536) && (height < 65536)) {
973         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);
974     } else {
975         g_warning("Calculated bitmap dimensions %d %d are out of range (1 - 65535). Nothing exported.", width, height);
976     }
978     g_slist_free (items);
982 /**
983  *  Perform an export of either PS or EPS.
984  *
985  *  \param doc Document to export.
986  *  \param uri URI to export to.
987  *  \param mime MIME type to export as.
988  */
990 static void do_export_ps(SPDocument* doc, gchar const* uri, char const* mime)
992     Inkscape::Extension::DB::OutputList o;
993     Inkscape::Extension::db.get_output_list(o);
994     Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
995     while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
996         i++;
997     }
999     if (i == o.end())
1000     {
1001         g_warning ("Could not find an extension to export this file.");
1002         return;
1003     }
1005     bool old_text_to_path = false;
1006     bool old_bbox_page = false;
1008     try {
1009         old_text_to_path = (*i)->get_param_bool("textToPath");
1010         (*i)->set_param_bool("textToPath", sp_export_text_to_path);
1011     }
1012     catch (...) {
1013         g_warning ("Could not set export-text-to-path option for this export.");
1014     }
1016     try {
1017         old_bbox_page = (*i)->get_param_bool("pageBoundingBox");
1018         (*i)->set_param_bool("pageBoundingBox", sp_export_bbox_page);
1019     }
1020     catch (...) {
1021         g_warning ("Could not set export-bbox-page option for this export.");
1022     }
1024     (*i)->save(doc, uri);
1026     try {
1027         (*i)->set_param_bool("textToPath", old_text_to_path);
1028         (*i)->set_param_bool("pageBoundingBox", old_bbox_page);
1029     }
1030     catch (...) {
1032     }
1035 /**
1036  *  Perform a PDF export
1037  *
1038  *  \param doc Document to export.
1039  *  \param uri URI to export to.
1040  *  \param mime MIME type to export as.
1041  */
1043 static void do_export_pdf(SPDocument* doc, gchar const* uri, char const* mime)
1045     Inkscape::Extension::DB::OutputList o;
1046     Inkscape::Extension::db.get_output_list(o);
1047     Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
1048     while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
1049         i++;
1050     }
1052     if (i == o.end())
1053     {
1054         g_warning ("Could not find an extension to export this file.");
1055         return;
1056     }
1058     (*i)->save(doc, uri);
1061 #ifdef WIN32
1062 bool replaceArgs( int& argc, char**& argv )
1064     bool worked = false;
1066 #ifdef REPLACEARGS_DEBUG
1067     MessageBoxA( NULL, "GetCommandLineW() getting called", "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1068 #endif // REPLACEARGS_DEBUG
1070     wchar_t* line = GetCommandLineW();
1071     if ( line )
1072     {
1073 #ifdef REPLACEARGS_DEBUG
1074         {
1075             gchar* utf8Line = g_utf16_to_utf8( (gunichar2*)line, -1, NULL, NULL, NULL );
1076             if ( utf8Line )
1077             {
1078                 gchar *safe = Inkscape::IO::sanitizeString(utf8Line);
1079                 {
1080                     char tmp[strlen(safe) + 32];
1081                     snprintf( tmp, sizeof(tmp), "GetCommandLineW() = '%s'", safe );
1082                     MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1083                 }
1084             }
1085         }
1086 #endif // REPLACEARGS_DEBUG
1088         int numArgs = 0;
1089         wchar_t** parsed = CommandLineToArgvW( line, &numArgs );
1091 #ifdef REPLACEARGS_ANSI
1092 // test code for trying things on Win95/98/ME
1093         if ( !parsed )
1094         {
1095 #ifdef REPLACEARGS_DEBUG
1096             MessageBoxA( NULL, "Unable to process command-line. Faking it", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1097 #endif // REPLACEARGS_DEBUG
1098             int lineLen = wcslen(line) + 1;
1099             wchar_t* lineDup = new wchar_t[lineLen];
1100             wcsncpy( lineDup, line, lineLen );
1102             int pos = 0;
1103             bool inQuotes = false;
1104             bool inWhitespace = true;
1105             std::vector<int> places;
1106             while ( lineDup[pos] )
1107             {
1108                 if ( inQuotes )
1109                 {
1110                     if ( lineDup[pos] == L'"' )
1111                     {
1112                         inQuotes = false;
1113                     }
1114                 }
1115                 else if ( lineDup[pos] == L'"' )
1116                 {
1117                     inQuotes = true;
1118                     inWhitespace = false;
1119                     places.push_back(pos);
1120                 }
1121                 else if ( lineDup[pos] == L' ' || lineDup[pos] == L'\t' )
1122                 {
1123                     if ( !inWhitespace )
1124                     {
1125                         inWhitespace = true;
1126                         lineDup[pos] = 0;
1127                     }
1128                 }
1129                 else if ( inWhitespace && (lineDup[pos] != L' ' && lineDup[pos] != L'\t') )
1130                 {
1131                     inWhitespace = false;
1132                     places.push_back(pos);
1133                 }
1134                 else
1135                 {
1136                     // consume
1137                 }
1138                 pos++;
1139             }
1140 #ifdef REPLACEARGS_DEBUG
1141             {
1142                 char tmp[256];
1143                 snprintf( tmp, sizeof(tmp), "Counted %d args", places.size() );
1144                 MessageBoxA( NULL, tmp, "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1145             }
1146 #endif // REPLACEARGS_DEBUG
1148             wchar_t** block = new wchar_t*[places.size()];
1149             int i = 0;
1150             for ( std::vector<int>::iterator it = places.begin(); it != places.end(); it++ )
1151             {
1152                 block[i++] = &lineDup[*it];
1153             }
1154             parsed = block;
1155             numArgs = places.size();
1156         }
1157 #endif // REPLACEARGS_ANSI
1159         if ( parsed )
1160         {
1161             std::vector<wchar_t*>expandedArgs;
1162             if ( numArgs > 0 )
1163             {
1164                 expandedArgs.push_back( parsed[0] );
1165             }
1167             for ( int i1 = 1; i1 < numArgs; i1++ )
1168             {
1169                 bool wildcarded = (wcschr(parsed[i1], L'?') != NULL) || (wcschr(parsed[i1], L'*') != NULL);
1170                 wildcarded &= parsed[i1][0] != L'"';
1171                 wildcarded &= parsed[i1][0] != L'-';
1172                 if ( wildcarded )
1173                 {
1174 #ifdef REPLACEARGS_ANSI
1175                     WIN32_FIND_DATAA data = {0};
1176 #else
1177                     WIN32_FIND_DATAW data = {0};
1178 #endif // REPLACEARGS_ANSI
1180                     int baseLen = wcslen(parsed[i1]) + 2;
1181                     wchar_t* base = new wchar_t[baseLen];
1182                     wcsncpy( base, parsed[i1], baseLen );
1183                     wchar_t* last = wcsrchr( base, L'\\' );
1184                     if ( last )
1185                     {
1186                         last[1] = 0;
1187                     }
1188                     else
1189                     {
1190                         base[0] = 0;
1191                     }
1192                     baseLen = wcslen( base );
1194 #ifdef REPLACEARGS_ANSI
1195                     char target[MAX_PATH];
1196                     if ( WideCharToMultiByte( CP_ACP, 0, parsed[i1], -1, target, sizeof(target), NULL, NULL) )
1197                     {
1198                         HANDLE hf = FindFirstFileA( target, &data );
1199 #else
1200                         HANDLE hf = FindFirstFileW( parsed[i1], &data );
1201 #endif // REPLACEARGS_ANSI
1202                         if ( hf != INVALID_HANDLE_VALUE )
1203                         {
1204                             BOOL found = TRUE;
1205                             do
1206                             {
1207 #ifdef REPLACEARGS_ANSI
1208                                 int howMany = MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, NULL, 0 );
1209                                 if ( howMany > 0 )
1210                                 {
1211                                     howMany += baseLen;
1212                                     wchar_t* tmp = new wchar_t[howMany + 1];
1213                                     wcsncpy( tmp, base, howMany + 1 );
1214                                     MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, tmp + baseLen, howMany + 1 - baseLen );
1215                                     expandedArgs.push_back( tmp );
1216                                     found = FindNextFileA( hf, &data );
1217                                 }
1218 #else
1219                                 int howMany = wcslen(data.cFileName) + baseLen;
1220                                 wchar_t* tmp = new wchar_t[howMany + 1];
1221                                 wcsncpy( tmp, base, howMany + 1 );
1222                                 wcsncat( tmp, data.cFileName, howMany + 1 );
1223                                 expandedArgs.push_back( tmp );
1224                                 found = FindNextFileW( hf, &data );
1225 #endif // REPLACEARGS_ANSI
1226                             } while ( found );
1228                             FindClose( hf );
1229                         }
1230                         else
1231                         {
1232                             expandedArgs.push_back( parsed[i1] );
1233                         }
1234 #ifdef REPLACEARGS_ANSI
1235                     }
1236 #endif // REPLACEARGS_ANSI
1238                     delete[] base;
1239                 }
1240                 else
1241                 {
1242                     expandedArgs.push_back( parsed[i1] );
1243                 }
1244             }
1246             {
1247                 wchar_t** block = new wchar_t*[expandedArgs.size()];
1248                 int iz = 0;
1249                 for ( std::vector<wchar_t*>::iterator it = expandedArgs.begin(); it != expandedArgs.end(); it++ )
1250                 {
1251                     block[iz++] = *it;
1252                 }
1253                 parsed = block;
1254                 numArgs = expandedArgs.size();
1255             }
1257             std::vector<gchar*> newArgs;
1258             for ( int i = 0; i < numArgs; i++ )
1259             {
1260                 gchar* replacement = g_utf16_to_utf8( (gunichar2*)parsed[i], -1, NULL, NULL, NULL );
1261                 if ( replacement )
1262                 {
1263 #ifdef REPLACEARGS_DEBUG
1264                     gchar *safe2 = Inkscape::IO::sanitizeString(replacement);
1266                     if ( safe2 )
1267                     {
1268                         {
1269                             char tmp[1024];
1270                             snprintf( tmp, sizeof(tmp), "    [%2d] = '%s'", i, safe2 );
1271                             MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1272                         }
1273                         g_free( safe2 );
1274                     }
1275 #endif // REPLACEARGS_DEBUG
1277                     newArgs.push_back( replacement );
1278                 }
1279                 else
1280                 {
1281                     newArgs.push_back( blankParam );
1282                 }
1283             }
1285             // Now push our munged params to be the new argv and argc
1286             {
1287                 char** block = new char*[newArgs.size()];
1288                 int iz = 0;
1289                 for ( std::vector<char*>::iterator it = newArgs.begin(); it != newArgs.end(); it++ )
1290                 {
1291                     block[iz++] = *it;
1292                 }
1293                 argv = block;
1294                 argc = newArgs.size();
1295                 worked = true;
1296             }
1297         }
1298 #ifdef REPLACEARGS_DEBUG
1299         else
1300         {
1301             MessageBoxA( NULL, "Unable to process command-line", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1302         }
1303 #endif // REPLACEARGS_DEBUG
1304     }
1305 #ifdef REPLACEARGS_DEBUG
1306     else
1307     {
1308         {
1309             MessageBoxA( NULL,  "Unable to fetch result from GetCommandLineW()", "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1310         }
1312         char* line2 = GetCommandLineA();
1313         if ( line2 )
1314         {
1315             gchar *safe = Inkscape::IO::sanitizeString(line2);
1316             {
1317                 {
1318                     char tmp[strlen(safe) + 32];
1319                     snprintf( tmp, sizeof(tmp), "GetCommandLineA() = '%s'", safe );
1320                     MessageBoxA( NULL, tmp, "GetCommandLineA", MB_OK | MB_ICONINFORMATION );
1321                 }
1322             }
1323         }
1324         else
1325         {
1326             MessageBoxA( NULL, "Unable to fetch result from GetCommandLineA()", "GetCommandLineA", MB_OK | MB_ICONINFORMATION );
1327         }
1328     }
1329 #endif // REPLACEARGS_DEBUG
1331     return worked;
1333 #endif // WIN32
1335 static GSList *
1336 sp_process_args(poptContext ctx)
1338     GSList *fl = NULL;
1340     gint a;
1341     while ((a = poptGetNextOpt(ctx)) >= 0) {
1342         switch (a) {
1343             case SP_ARG_FILE: {
1344                 gchar const *fn = poptGetOptArg(ctx);
1345                 if (fn != NULL) {
1346                     fl = g_slist_append(fl, g_strdup(fn));
1347                 }
1348                 break;
1349             }
1350             case SP_ARG_VERSION: {
1351                 printf("Inkscape %s (%s)\n", INKSCAPE_VERSION, __DATE__);
1352                 exit(0);
1353                 break;
1354             }
1355             case SP_ARG_EXTENSIONDIR: {
1356                 printf("%s\n", INKSCAPE_EXTENSIONDIR);
1357                 exit(0);
1358                 break;
1359             }
1360             default: {
1361                 break;
1362             }
1363         }
1364     }
1366     gchar const ** const args = poptGetArgs(ctx);
1367     if (args != NULL) {
1368         for (unsigned i = 0; args[i] != NULL; i++) {
1369             fl = g_slist_append(fl, g_strdup(args[i]));
1370         }
1371     }
1373     return fl;
1377 /*
1378   Local Variables:
1379   mode:c++
1380   c-file-style:"stroustrup"
1381   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
1382   indent-tabs-mode:nil
1383   fill-column:99
1384   End:
1385 */
1386 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :