Code

improve streaming
[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_FONT,
138     SP_ARG_EXPORT_BBOX_PAGE,
139     SP_ARG_EXTENSIONDIR,
140     SP_ARG_SLIDESHOW,
141     SP_ARG_QUERY_X,
142     SP_ARG_QUERY_Y,
143     SP_ARG_QUERY_WIDTH,
144     SP_ARG_QUERY_HEIGHT,
145     SP_ARG_QUERY_ID,
146     SP_ARG_VERSION,
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_font = FALSE;
180 static gboolean sp_export_bbox_page = FALSE;
181 static gboolean sp_query_x = FALSE;
182 static gboolean sp_query_y = FALSE;
183 static gboolean sp_query_width = FALSE;
184 static gboolean sp_query_height = FALSE;
185 static gchar *sp_query_id = NULL;
186 static int sp_new_gui = FALSE;
187 static gboolean sp_vacuum_defs = FALSE;
189 static gchar *sp_export_png_utf8 = NULL;
190 static gchar *sp_export_svg_utf8 = NULL;
191 static gchar *sp_global_printer_utf8 = NULL;
193 #ifdef WIN32
194 static bool replaceArgs( int& argc, char**& argv );
195 #endif
196 static GSList *sp_process_args(poptContext ctx);
197 struct poptOption options[] = {
198     {"version", 'V',
199      POPT_ARG_NONE, NULL, SP_ARG_VERSION,
200      N_("Print the Inkscape version number"),
201      NULL},
203     {"without-gui", 'z',
204      POPT_ARG_NONE, NULL, SP_ARG_NOGUI,
205      N_("Do not use X server (only process files from console)"),
206      NULL},
208     {"with-gui", 'g',
209      POPT_ARG_NONE, NULL, SP_ARG_GUI,
210      N_("Try to use X server (even if $DISPLAY is not set)"),
211      NULL},
213     {"file", 'f',
214      POPT_ARG_STRING, NULL, SP_ARG_FILE,
215      N_("Open specified document(s) (option string may be excluded)"),
216      N_("FILENAME")},
218     {"print", 'p',
219      POPT_ARG_STRING, &sp_global_printer, SP_ARG_PRINT,
220      N_("Print document(s) to specified output file (use '| program' for pipe)"),
221      N_("FILENAME")},
223     {"export-png", 'e',
224      POPT_ARG_STRING, &sp_export_png, SP_ARG_EXPORT_PNG,
225      N_("Export document to a PNG file"),
226      N_("FILENAME")},
228     {"export-dpi", 'd',
229      POPT_ARG_STRING, &sp_export_dpi, SP_ARG_EXPORT_DPI,
230      N_("The resolution used for exporting SVG into bitmap (default 90)"),
231      N_("DPI")},
233     {"export-area", 'a',
234      POPT_ARG_STRING, &sp_export_area, SP_ARG_EXPORT_AREA,
235      N_("Exported area in SVG user units (default is the canvas; 0,0 is lower-left corner)"),
236      N_("x0:y0:x1:y1")},
238     {"export-area-drawing", 'D',
239      POPT_ARG_NONE, &sp_export_area_drawing, SP_ARG_EXPORT_AREA_DRAWING,
240      N_("Exported area is the entire drawing (not canvas)"),
241      NULL},
243     {"export-area-canvas", 'C',
244      POPT_ARG_NONE, &sp_export_area_canvas, SP_ARG_EXPORT_AREA_CANVAS,
245      N_("Exported area is the entire canvas"),
246      NULL},
248     {"export-area-snap", 0,
249      POPT_ARG_NONE, &sp_export_area_snap, SP_ARG_EXPORT_AREA_SNAP,
250      N_("Snap the bitmap export area outwards to the nearest integer values (in SVG user units)"),
251      NULL},
253     {"export-width", 'w',
254      POPT_ARG_STRING, &sp_export_width, SP_ARG_EXPORT_WIDTH,
255      N_("The width of exported bitmap in pixels (overrides export-dpi)"),
256      N_("WIDTH")},
258     {"export-height", 'h',
259      POPT_ARG_STRING, &sp_export_height, SP_ARG_EXPORT_HEIGHT,
260      N_("The height of exported bitmap in pixels (overrides export-dpi)"),
261      N_("HEIGHT")},
263     {"export-id", 'i',
264      POPT_ARG_STRING, &sp_export_id, SP_ARG_EXPORT_ID,
265      N_("The ID of the object to export"),
266      N_("ID")},
268     {"export-id-only", 'j',
269      POPT_ARG_NONE, &sp_export_id_only, SP_ARG_EXPORT_ID_ONLY,
270      // TRANSLATORS: this means: "Only export the object whose id is given in --export-id".
271      //  See "man inkscape" for details.
272      N_("Export just the object with export-id, hide all others (only with export-id)"),
273      NULL},
275     {"export-use-hints", 't',
276      POPT_ARG_NONE, &sp_export_use_hints, SP_ARG_EXPORT_USE_HINTS,
277      N_("Use stored filename and DPI hints when exporting (only with export-id)"),
278      NULL},
280     {"export-background", 'b',
281      POPT_ARG_STRING, &sp_export_background, SP_ARG_EXPORT_BACKGROUND,
282      N_("Background color of exported bitmap (any SVG-supported color string)"),
283      N_("COLOR")},
285     {"export-background-opacity", 'y',
286      POPT_ARG_STRING, &sp_export_background_opacity, SP_ARG_EXPORT_BACKGROUND_OPACITY,
287      N_("Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)"),
288      N_("VALUE")},
290     {"export-plain-svg", 'l',
291      POPT_ARG_STRING, &sp_export_svg, SP_ARG_EXPORT_SVG,
292      N_("Export document to plain SVG file (no sodipodi or inkscape namespaces)"),
293      N_("FILENAME")},
295     {"export-ps", 'P',
296      POPT_ARG_STRING, &sp_export_ps, SP_ARG_EXPORT_PS,
297      N_("Export document to a PS file"),
298      N_("FILENAME")},
300     {"export-eps", 'E',
301      POPT_ARG_STRING, &sp_export_eps, SP_ARG_EXPORT_EPS,
302      N_("Export document to an EPS file"),
303      N_("FILENAME")},
305     {"export-pdf", 'A',
306      POPT_ARG_STRING, &sp_export_pdf, SP_ARG_EXPORT_PDF,
307      N_("Export document to a PDF file"),
308      N_("FILENAME")},
310     {"export-text-to-path", 'T',
311      POPT_ARG_NONE, &sp_export_text_to_path, SP_ARG_EXPORT_TEXT_TO_PATH,
312      N_("Convert text object to paths on export (EPS)"),
313      NULL},
315     {"export-embed-fonts", 'F',
316      POPT_ARG_NONE, &sp_export_font, SP_ARG_EXPORT_FONT,
317      N_("Embed fonts on export (Type 1 only) (EPS)"),
318      NULL},
320     {"export-bbox-page", 'B',
321      POPT_ARG_NONE, &sp_export_bbox_page, SP_ARG_EXPORT_BBOX_PAGE,
322      N_("Export files with the bounding box set to the page size (EPS)"),
323      NULL},
325     {"query-x", 'X',
326      POPT_ARG_NONE, &sp_query_x, SP_ARG_QUERY_X,
327      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
328      N_("Query the X coordinate of the drawing or, if specified, of the object with --query-id"),
329      NULL},
331     {"query-y", 'Y',
332      POPT_ARG_NONE, &sp_query_y, SP_ARG_QUERY_Y,
333      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
334      N_("Query the Y coordinate of the drawing or, if specified, of the object with --query-id"),
335      NULL},
337     {"query-width", 'W',
338      POPT_ARG_NONE, &sp_query_width, SP_ARG_QUERY_WIDTH,
339      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
340      N_("Query the width of the drawing or, if specified, of the object with --query-id"),
341      NULL},
343     {"query-height", 'H',
344      POPT_ARG_NONE, &sp_query_height, SP_ARG_QUERY_HEIGHT,
345      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
346      N_("Query the height of the drawing or, if specified, of the object with --query-id"),
347      NULL},
349     {"query-id", 'I',
350      POPT_ARG_STRING, &sp_query_id, SP_ARG_QUERY_ID,
351      N_("The ID of the object whose dimensions are queried"),
352      N_("ID")},
354     {"extension-directory", 'x',
355      POPT_ARG_NONE, NULL, SP_ARG_EXTENSIONDIR,
356      // TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory
357      N_("Print out the extension directory and exit"),
358      NULL},
360     {"slideshow", 's',
361      POPT_ARG_NONE, &sp_global_slideshow, SP_ARG_SLIDESHOW,
362      N_("Show given files one-by-one, switch to next on any key/mouse event"),
363      NULL},
365     {"vacuum-defs", 0,
366      POPT_ARG_NONE, &sp_vacuum_defs, SP_ARG_VACUUM_DEFS,
367      N_("Remove unused definitions from the defs section(s) of the document"),
368      NULL},
370     POPT_AUTOHELP POPT_TABLEEND
371 };
373 static bool needToRecodeParams = true;
374 gchar* blankParam = "";
376 int
377 main(int argc, char **argv)
379 #ifdef HAVE_FPSETMASK
380     /* This is inherited from Sodipodi code, where it was in #ifdef __FreeBSD__.  It's probably
381        safe to remove: the default mask is already 0 in C99, and in current FreeBSD according to
382        the fenv man page on www.freebsd.org, and in glibc according to (libc)FP Exceptions. */
383     fpsetmask(fpgetmask() & ~(FP_X_DZ | FP_X_INV));
384 #endif
386 #ifdef ENABLE_NLS
387 #ifdef WIN32
388     RegistryTool rt;
389     rt.setPathInfo();
390     gchar *pathBuf = g_strconcat(g_path_get_dirname(argv[0]), "\\", PACKAGE_LOCALE_DIR, NULL);
391     bindtextdomain(GETTEXT_PACKAGE, pathBuf);
392     g_free(pathBuf);
393 #else
394 #ifdef ENABLE_BINRELOC
395     bindtextdomain(GETTEXT_PACKAGE, BR_LOCALEDIR(""));
396 #else
397     bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
398 #endif
399 #endif
400 #endif
402     bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
404 #ifdef ENABLE_NLS
405     textdomain(GETTEXT_PACKAGE);
406 #endif
408     LIBXML_TEST_VERSION
410     Inkscape::GC::init();
412     Inkscape::Debug::Logger::init();
414     gboolean use_gui;
415 #ifndef WIN32
416     use_gui = (getenv("DISPLAY") != NULL);
417 #else
418     /*
419       Set the current directory to the directory of the
420       executable.  This seems redundant, but is needed for
421       when inkscape.exe is executed from another directory.
422       We use relative paths on win32.
423       HKCR\svgfile\shell\open\command is a good example
424     */
425     /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
426     char *homedir = g_path_get_dirname(argv[0]);
427     SetCurrentDirectory(homedir);
428     g_free(homedir);
430     use_gui = TRUE;
431 #endif
432     /* Test whether with/without GUI is forced */
433     for (int i = 1; i < argc; i++) {
434         if (!strcmp(argv[i], "-z")
435             || !strcmp(argv[i], "--without-gui")
436             || !strcmp(argv[i], "-p")
437             || !strncmp(argv[i], "--print", 7)
438             || !strcmp(argv[i], "-e")
439             || !strncmp(argv[i], "--export-png", 12)
440             || !strcmp(argv[i], "-l")
441             || !strncmp(argv[i], "--export-plain-svg", 12)
442             || !strcmp(argv[i], "-i")
443             || !strncmp(argv[i], "--export-area-drawing", 21)
444             || !strcmp(argv[i], "-D")
445             || !strncmp(argv[i], "--export-area-canvas", 20)
446             || !strcmp(argv[i], "-C")
447             || !strncmp(argv[i], "--export-id", 12)
448             || !strcmp(argv[i], "-P")
449             || !strncmp(argv[i], "--export-ps", 11)
450             || !strcmp(argv[i], "-E")
451             || !strncmp(argv[i], "--export-eps", 12)
452             || !strcmp(argv[i], "-A")
453             || !strncmp(argv[i], "--export-pdf", 12)
454             || !strcmp(argv[i], "-W")
455             || !strncmp(argv[i], "--query-width", 13)
456             || !strcmp(argv[i], "-H")
457             || !strncmp(argv[i], "--query-height", 14)
458             || !strcmp(argv[i], "-X")
459             || !strncmp(argv[i], "--query-x", 13)
460             || !strcmp(argv[i], "-Y")
461             || !strncmp(argv[i], "--query-y", 14)
462             || !strcmp(argv[i], "--vacuum-defs")
463            )
464         {
465             /* main_console handles any exports -- not the gui */
466             use_gui = FALSE;
467             break;
468         } else if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--with-gui")) {
469             use_gui = TRUE;
470             break;
471         }
472     }
474 #ifdef WIN32
475 #ifndef REPLACEARGS_ANSI
476     if ( PrintWin32::is_os_wide() )
477 #endif // REPLACEARGS_ANSI
478     {
479         // If the call fails, we'll need to convert charsets
480         needToRecodeParams = !replaceArgs( argc, argv );
481     }
482 #endif // WIN32
484     /// \todo  Should this be a static object (see inkscape.cpp)?
485     Inkscape::NSApplication::Application app(argc, argv, use_gui, sp_new_gui);
487     return app.run();
490 void fixupSingleFilename( gchar **orig, gchar **spare )
492     if ( orig && *orig && **orig ) {
493         GError *error = NULL;
494         gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(*orig, -1, NULL, NULL, &error);
495         if ( newFileName )
496         {
497             *orig = newFileName;
498             if ( spare ) {
499                 *spare = newFileName;
500             }
501 //             g_message("Set a replacement fixup");
502         }
503     }
506 GSList *fixupFilenameEncoding( GSList* fl )
508     GSList *newFl = NULL;
509     while ( fl ) {
510         gchar *fn = static_cast<gchar*>(fl->data);
511         fl = g_slist_remove( fl, fl->data );
512         gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(fn, -1, NULL, NULL, NULL);
513         if ( newFileName ) {
515             if ( 0 )
516             {
517                 gchar *safeFn = Inkscape::IO::sanitizeString(fn);
518                 gchar *safeNewFn = Inkscape::IO::sanitizeString(newFileName);
519                 GtkWidget *w = gtk_message_dialog_new( NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
520                                                        "Note: Converted '%s' to '%s'", safeFn, safeNewFn );
521                 gtk_dialog_run (GTK_DIALOG (w));
522                 gtk_widget_destroy (w);
523                 g_free(safeNewFn);
524                 g_free(safeFn);
525             }
527             g_free( fn );
528             fn = newFileName;
529             newFileName = 0;
530         }
531         else
532             if ( 0 )
533         {
534             gchar *safeFn = Inkscape::IO::sanitizeString(fn);
535             GtkWidget *w = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "Error: Unable to convert '%s'", safeFn );
536             gtk_dialog_run (GTK_DIALOG (w));
537             gtk_widget_destroy (w);
538             g_free(safeFn);
539         }
540         newFl = g_slist_append( newFl, fn );
541     }
542     return newFl;
545 int sp_common_main( int argc, char const **argv, GSList **flDest )
547     /// \todo fixme: Move these to some centralized location (Lauris)
548     sp_object_type_register("sodipodi:namedview", SP_TYPE_NAMEDVIEW);
549     sp_object_type_register("sodipodi:guide", SP_TYPE_GUIDE);
552     // temporarily switch gettext encoding to locale, so that help messages can be output properly
553     gchar const *charset;
554     g_get_charset(&charset);
556     bind_textdomain_codeset(GETTEXT_PACKAGE, charset);
558     poptContext ctx = poptGetContext(NULL, argc, argv, options, 0);
559     poptSetOtherOptionHelp(ctx, _("[OPTIONS...] [FILE...]\n\nAvailable options:"));
560     g_return_val_if_fail(ctx != NULL, 1);
562     /* Collect own arguments */
563     GSList *fl = sp_process_args(ctx);
564     poptFreeContext(ctx);
566     // now switch gettext back to UTF-8 (for GUI)
567     bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
569     // Now let's see if the file list still holds up
570     if ( needToRecodeParams )
571     {
572         fl = fixupFilenameEncoding( fl );
573     }
575     // Check the globals for filename-fixup
576     if ( needToRecodeParams )
577     {
578         fixupSingleFilename( &sp_export_png, &sp_export_png_utf8 );
579         fixupSingleFilename( &sp_export_svg, &sp_export_svg_utf8 );
580         fixupSingleFilename( &sp_global_printer, &sp_global_printer_utf8 );
581     }
582     else
583     {
584         if ( sp_export_png )
585             sp_export_png_utf8 = g_strdup( sp_export_png );
586         if ( sp_export_svg )
587             sp_export_svg_utf8 = g_strdup( sp_export_svg );
588         if ( sp_global_printer )
589             sp_global_printer_utf8 = g_strdup( sp_global_printer );
590     }
592     // Return the list if wanted, else free it up.
593     if ( flDest ) {
594         *flDest = fl;
595         fl = 0;
596     } else {
597         while ( fl ) {
598             g_free( fl->data );
599             fl = g_slist_remove( fl, fl->data );
600         }
601     }
602     return 0;
605 int
606 sp_main_gui(int argc, char const **argv)
608     Gtk::Main main_instance (&argc, const_cast<char ***>(&argv));
610     GSList *fl = NULL;
611     int retVal = sp_common_main( argc, argv, &fl );
612     g_return_val_if_fail(retVal == 0, 1);
614     inkscape_gtk_stock_init();
616     /* Set default icon */
617     gchar *filename = (gchar *) g_build_filename (INKSCAPE_APPICONDIR, "inkscape.png", NULL);
618     if (Inkscape::IO::file_test(filename, (GFileTest)(G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK))) {
619         gtk_window_set_default_icon_from_file(filename, NULL);
620     }
621     g_free (filename);
622     filename = 0;
624     if (!sp_global_slideshow) {
625         gboolean create_new = TRUE;
627         /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
628         inkscape_application_init(argv[0], true);
630         while (fl) {
631             if (sp_file_open((gchar *)fl->data,NULL)) {
632                 create_new=FALSE;
633             }
634             fl = g_slist_remove(fl, fl->data);
635         }
636         if (create_new) {
637             sp_file_new_default();
638         }
639     } else {
640         if (fl) {
641             GtkWidget *ss;
642             /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
643             inkscape_application_init(argv[0], true);
644             ss = sp_slideshow_new(fl);
645             if (ss) gtk_widget_show(ss);
646         } else {
647             g_warning ("No slides to display");
648             exit(0);
649         }
650     }
652     main_instance.run();
654 #ifdef WIN32
655     //We might not need anything here
656     //sp_win32_finish(); <-- this is a NOP func
657 #endif
659     return 0;
662 int
663 sp_main_console(int argc, char const **argv)
665     /* We are started in text mode */
667     /* Do this g_type_init(), so that we can use Xft/Freetype2 (Pango)
668      * in a non-Gtk environment.  Used in libnrtype's
669      * FontInstance.cpp and FontFactory.cpp.
670      * http://mail.gnome.org/archives/gtk-list/2003-December/msg00063.html
671      */
672     g_type_init();
673     char **argv2 = const_cast<char **>(argv);
674     gtk_init_check( &argc, &argv2 );
675     //setlocale(LC_ALL, "");
677     GSList *fl = NULL;
678     int retVal = sp_common_main( argc, argv, &fl );
679     g_return_val_if_fail(retVal == 0, 1);
681     if (fl == NULL) {
682         g_print("Nothing to do!\n");
683         exit(0);
684     }
686     inkscape_application_init(argv[0], false);
688     while (fl) {
689         SPDocument *doc;
691         doc = Inkscape::Extension::open(NULL, (gchar *)fl->data);
692         if (doc == NULL) {
693             doc = Inkscape::Extension::open(Inkscape::Extension::db.get(SP_MODULE_KEY_INPUT_SVG), (gchar *)fl->data);
694         }
695         if (doc == NULL) {
696             g_warning("Specified document %s cannot be opened (is it valid SVG file?)", (gchar *) fl->data);
697         } else {
698             if (sp_vacuum_defs) {
699                 vacuum_document(doc);
700             }
701             if (sp_vacuum_defs && !sp_export_svg) {
702                 // save under the name given in the command line
703                 sp_repr_save_file(doc->rdoc, (gchar *)fl->data, SP_SVG_NS_URI);
704             }
705             if (sp_global_printer) {
706                 sp_print_document_to_file(doc, sp_global_printer);
707             }
708             if (sp_export_png || sp_export_id || sp_export_area_drawing) {
709                 sp_do_export_png(doc);
710             }
711             if (sp_export_svg) {
712                 Inkscape::XML::Document *rdoc;
713                 Inkscape::XML::Node *repr;
714                 rdoc = sp_repr_document_new("svg:svg");
715                 repr = rdoc->root();
716                 repr = sp_document_root(doc)->updateRepr(repr, SP_OBJECT_WRITE_BUILD);
717                 sp_repr_save_file(repr->document(), sp_export_svg, SP_SVG_NS_URI);
718             }
719             if (sp_export_ps) {
720                 do_export_ps(doc, sp_export_ps, "image/x-postscript");
721             }
722             if (sp_export_eps) {
723                 do_export_ps(doc, sp_export_eps, "image/x-e-postscript");
724             }
725             if (sp_export_pdf) {
726                 do_export_pdf(doc, sp_export_pdf, "application/pdf");
727             }
728             if (sp_query_width || sp_query_height) {
729                 do_query_dimension (doc, true, sp_query_width? NR::X : NR::Y, sp_query_id);
730             } else if (sp_query_x || sp_query_y) {
731                 do_query_dimension (doc, false, sp_query_x? NR::X : NR::Y, sp_query_id);
732             }
733         }
734         fl = g_slist_remove(fl, fl->data);
735     }
737     inkscape_unref();
739     return 0;
742 static void
743 do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gchar *id)
745     SPObject *o = NULL;
747     if (id) {
748         o = doc->getObjectById(id);
749         if (o) {
750             if (!SP_IS_ITEM (o)) {
751                 g_warning("Object with id=\"%s\" is not a visible item. Cannot query dimensions.", id);
752                 return;
753             }
754         } else {
755             g_warning("Object with id=\"%s\" is not found. Cannot query dimensions.", id);
756             return;
757         }
758     } else {
759         o = SP_DOCUMENT_ROOT(doc);
760     }
762     if (o) {
763         sp_document_ensure_up_to_date (doc);
764         SPItem *item = ((SPItem *) o);
765         NR::Rect area = item->invokeBbox(sp_item_i2doc_affine(item)); // "true" SVG bbox for scripting
767         Inkscape::SVGOStringStream os;
768         if (extent) {
769             os << area.extent(axis);
770         } else {
771             os << area.min()[axis];
772         }
773         g_print ("%s", os.str().c_str());
774     }
778 static void
779 sp_do_export_png(SPDocument *doc)
781     const gchar *filename = NULL;
782     gdouble dpi = 0.0;
784     if (sp_export_use_hints && (!sp_export_id && !sp_export_area_drawing)) {
785         g_warning ("--export-use-hints can only be used with --export-id or --export-area-drawing; ignored.");
786     }
788     GSList *items = NULL;
790     NRRect area;
791     if (sp_export_id || sp_export_area_drawing) {
793         SPObject *o = NULL;
794         SPObject *o_area = NULL;
795         if (sp_export_id && sp_export_area_drawing) {
796             o = doc->getObjectById(sp_export_id);
797             o_area = SP_DOCUMENT_ROOT (doc);
798         } else if (sp_export_id) {
799             o = doc->getObjectById(sp_export_id);
800             o_area = o;
801         } else if (sp_export_area_drawing) {
802             o = SP_DOCUMENT_ROOT (doc);
803             o_area = o;
804         } 
806         if (o) {
807             if (!SP_IS_ITEM (o)) {
808                 g_warning("Object with id=\"%s\" is not a visible item. Nothing exported.", sp_export_id);
809                 return;
810             }
812             items = g_slist_prepend (items, SP_ITEM(o));
814             if (sp_export_id_only) {
815                 g_print("Exporting only object with id=\"%s\"; all other objects hidden\n", sp_export_id);
816             }
818             if (sp_export_use_hints) {
820                 // retrieve export filename hint
821                 const gchar *fn_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-filename");
822                 if (fn_hint) {
823                     if (sp_export_png) {
824                         g_warning ("Using export filename from the command line (--export-png). Filename hint %s is ignored.", fn_hint);
825                         filename = sp_export_png;
826                     } else {
827                         filename = fn_hint;
828                     }
829                 } else {
830                     g_warning ("Export filename hint not found for the object.");
831                     filename = sp_export_png;
832                 }
834                 // retrieve export dpi hints
835                 const gchar *dpi_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-xdpi"); // only xdpi, ydpi is always the same now
836                 if (dpi_hint) {
837                     if (sp_export_dpi || sp_export_width || sp_export_height) {
838                         g_warning ("Using bitmap dimensions from the command line (--export-dpi, --export-width, or --export-height). DPI hint %s is ignored.", dpi_hint);
839                     } else {
840                         dpi = atof(dpi_hint);
841                     }
842                 } else {
843                     g_warning ("Export DPI hint not found for the object.");
844                 }
846             }
848             // write object bbox to area
849             sp_document_ensure_up_to_date (doc);
850             sp_item_invoke_bbox((SPItem *) o_area, &area, sp_item_i2r_affine((SPItem *) o_area), TRUE);
851         } else {
852             g_warning("Object with id=\"%s\" was not found in the document. Nothing exported.", sp_export_id);
853             return;
854         }
855     }
856     
857     if (sp_export_area) {
858         /* Try to parse area (given in SVG pixels) */
859         if (!sscanf(sp_export_area, "%lg:%lg:%lg:%lg", &area.x0, &area.y0, &area.x1, &area.y1) == 4) {
860             g_warning("Cannot parse export area '%s'; use 'x0:y0:x1:y1'. Nothing exported.", sp_export_area);
861             return;
862         }
863         if ((area.x0 >= area.x1) || (area.y0 >= area.y1)) {
864             g_warning("Export area '%s' has negative width or height. Nothing exported.", sp_export_area);
865             return;
866         }
867     } else if (sp_export_area_canvas || !(sp_export_id || sp_export_area_drawing)) {
868         /* Export the whole canvas */
869         sp_document_ensure_up_to_date (doc);
870         area.x0 = SP_ROOT(doc->root)->x.computed;
871         area.y0 = SP_ROOT(doc->root)->y.computed;
872         area.x1 = area.x0 + sp_document_width (doc);
873         area.y1 = area.y0 + sp_document_height (doc);
874     }
876     // set filename and dpi from options, if not yet set from the hints
877     if (!filename) {
878         if (!sp_export_png) {
879             g_warning ("No export filename given and no filename hint. Nothing exported.");
880             return;
881         }
882         filename = sp_export_png;
883     }
885     if (sp_export_dpi && dpi == 0.0) {
886         dpi = atof(sp_export_dpi);
887         if ((dpi < 0.1) || (dpi > 10000.0)) {
888             g_warning("DPI value %s out of range [0.1 - 10000.0]. Nothing exported.", sp_export_dpi);
889             return;
890         }
891         g_print("DPI: %g\n", dpi);
892     }
894     if (sp_export_area_snap) {
895         area.x0 = std::floor (area.x0);
896         area.y0 = std::floor (area.y0);
897         area.x1 = std::ceil (area.x1);
898         area.y1 = std::ceil (area.y1);
899     }
901     // default dpi
902     if (dpi == 0.0)
903         dpi = PX_PER_IN;
905     gint width = 0;
906     gint height = 0;
908     if (sp_export_width) {
909         width = atoi(sp_export_width);
910         if ((width < 1) || (width > 65536)) {
911             g_warning("Export width %d out of range (1 - 65536). Nothing exported.", width);
912             return;
913         }
914         dpi = (gdouble) width * PX_PER_IN / (area.x1 - area.x0);
915     }
917     if (sp_export_height) {
918         height = atoi(sp_export_height);
919         if ((height < 1) || (height > 65536)) {
920             g_warning("Export height %d out of range (1 - 65536). Nothing exported.", width);
921             return;
922         }
923         dpi = (gdouble) height * PX_PER_IN / (area.y1 - area.y0);
924     }
926     if (!sp_export_width) {
927         width = (gint) ((area.x1 - area.x0) * dpi / PX_PER_IN + 0.5);
928     }
930     if (!sp_export_height) {
931         height = (gint) ((area.y1 - area.y0) * dpi / PX_PER_IN + 0.5);
932     }
934     guint32 bgcolor = 0x00000000;
935     if (sp_export_background) {
936         // override the page color
937         bgcolor = sp_svg_read_color(sp_export_background, 0xffffff00);
938         bgcolor |= 0xff; // default is no opacity
939     } else {
940         // read from namedview
941         Inkscape::XML::Node *nv = sp_repr_lookup_name (doc->rroot, "sodipodi:namedview");
942         if (nv && nv->attribute("pagecolor"))
943             bgcolor = sp_svg_read_color(nv->attribute("pagecolor"), 0xffffff00);
944         if (nv && nv->attribute("inkscape:pageopacity"))
945             bgcolor |= SP_COLOR_F_TO_U(sp_repr_get_double_attribute (nv, "inkscape:pageopacity", 1.0));
946     }
948     if (sp_export_background_opacity) {
949         // override opacity
950         gfloat value;
951         if (sp_svg_number_read_f (sp_export_background_opacity, &value)) {
952             if (value > 1.0) {
953                 value = CLAMP (value, 1.0f, 255.0f);
954                 bgcolor &= (guint32) 0xffffff00;
955                 bgcolor |= (guint32) floor(value);
956             } else {
957                 value = CLAMP (value, 0.0f, 1.0f);
958                 bgcolor &= (guint32) 0xffffff00;
959                 bgcolor |= SP_COLOR_F_TO_U(value);
960             }
961         }
962     }
964     g_print("Background RRGGBBAA: %08x\n", bgcolor);
966     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);
968     g_print("Bitmap saved as: %s\n", filename);
970     if ((width >= 1) && (height >= 1) && (width < 65536) && (height < 65536)) {
971         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);
972     } else {
973         g_warning("Calculated bitmap dimensions %d %d are out of range (1 - 65535). Nothing exported.", width, height);
974     }
976     g_slist_free (items);
980 /**
981  *  Perform an export of either PS or EPS.
982  *
983  *  \param doc Document to export.
984  *  \param uri URI to export to.
985  *  \param mime MIME type to export as.
986  */
988 static void do_export_ps(SPDocument* doc, gchar const* uri, char const* mime)
990     Inkscape::Extension::DB::OutputList o;
991     Inkscape::Extension::db.get_output_list(o);
992     Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
993     while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
994         i++;
995     }
997     if (i == o.end())
998     {
999         g_warning ("Could not find an extension to export this file.");
1000         return;
1001     }
1003     bool old_text_to_path = false;
1004     bool old_font_embedded = false;
1005     bool old_bbox_page = false;
1007     try {
1008         old_text_to_path = (*i)->get_param_bool("textToPath");
1009         (*i)->set_param_bool("textToPath", sp_export_text_to_path);
1010     }
1011     catch (...) {
1012         g_warning ("Could not set export-text-to-path option for this export.");
1013     }
1015     try {
1016         old_font_embedded = (*i)->get_param_bool("fontEmbedded");
1017         (*i)->set_param_bool("fontEmbedded", sp_export_font);
1018     }
1019     catch (...) {
1020         g_warning ("Could not set export-font option for this export.");
1021     }
1023     try {
1024         old_bbox_page = (*i)->get_param_bool("pageBoundingBox");
1025         (*i)->set_param_bool("pageBoundingBox", sp_export_bbox_page);
1026     }
1027     catch (...) {
1028         g_warning ("Could not set export-bbox-page option for this export.");
1029     }
1031     (*i)->save(doc, uri);
1033     try {
1034         (*i)->set_param_bool("textToPath", old_text_to_path);
1035         (*i)->set_param_bool("fontEmbedded", old_font_embedded);
1036         (*i)->set_param_bool("pageBoundingBox", old_bbox_page);
1037     }
1038     catch (...) {
1040     }
1043 /**
1044  *  Perform a PDF export
1045  *
1046  *  \param doc Document to export.
1047  *  \param uri URI to export to.
1048  *  \param mime MIME type to export as.
1049  */
1051 static void do_export_pdf(SPDocument* doc, gchar const* uri, char const* mime)
1053     Inkscape::Extension::DB::OutputList o;
1054     Inkscape::Extension::db.get_output_list(o);
1055     Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
1056     while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
1057         i++;
1058     }
1060     if (i == o.end())
1061     {
1062         g_warning ("Could not find an extension to export this file.");
1063         return;
1064     }
1066     (*i)->save(doc, uri);
1069 #ifdef WIN32
1070 bool replaceArgs( int& argc, char**& argv )
1072     bool worked = false;
1074 #ifdef REPLACEARGS_DEBUG
1075     MessageBoxA( NULL, "GetCommandLineW() getting called", "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1076 #endif // REPLACEARGS_DEBUG
1078     wchar_t* line = GetCommandLineW();
1079     if ( line )
1080     {
1081 #ifdef REPLACEARGS_DEBUG
1082         {
1083             gchar* utf8Line = g_utf16_to_utf8( (gunichar2*)line, -1, NULL, NULL, NULL );
1084             if ( utf8Line )
1085             {
1086                 gchar *safe = Inkscape::IO::sanitizeString(utf8Line);
1087                 {
1088                     char tmp[strlen(safe) + 32];
1089                     snprintf( tmp, sizeof(tmp), "GetCommandLineW() = '%s'", safe );
1090                     MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1091                 }
1092             }
1093         }
1094 #endif // REPLACEARGS_DEBUG
1096         int numArgs = 0;
1097         wchar_t** parsed = CommandLineToArgvW( line, &numArgs );
1099 #ifdef REPLACEARGS_ANSI
1100 // test code for trying things on Win95/98/ME
1101         if ( !parsed )
1102         {
1103 #ifdef REPLACEARGS_DEBUG
1104             MessageBoxA( NULL, "Unable to process command-line. Faking it", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1105 #endif // REPLACEARGS_DEBUG
1106             int lineLen = wcslen(line) + 1;
1107             wchar_t* lineDup = new wchar_t[lineLen];
1108             wcsncpy( lineDup, line, lineLen );
1110             int pos = 0;
1111             bool inQuotes = false;
1112             bool inWhitespace = true;
1113             std::vector<int> places;
1114             while ( lineDup[pos] )
1115             {
1116                 if ( inQuotes )
1117                 {
1118                     if ( lineDup[pos] == L'"' )
1119                     {
1120                         inQuotes = false;
1121                     }
1122                 }
1123                 else if ( lineDup[pos] == L'"' )
1124                 {
1125                     inQuotes = true;
1126                     inWhitespace = false;
1127                     places.push_back(pos);
1128                 }
1129                 else if ( lineDup[pos] == L' ' || lineDup[pos] == L'\t' )
1130                 {
1131                     if ( !inWhitespace )
1132                     {
1133                         inWhitespace = true;
1134                         lineDup[pos] = 0;
1135                     }
1136                 }
1137                 else if ( inWhitespace && (lineDup[pos] != L' ' && lineDup[pos] != L'\t') )
1138                 {
1139                     inWhitespace = false;
1140                     places.push_back(pos);
1141                 }
1142                 else
1143                 {
1144                     // consume
1145                 }
1146                 pos++;
1147             }
1148 #ifdef REPLACEARGS_DEBUG
1149             {
1150                 char tmp[256];
1151                 snprintf( tmp, sizeof(tmp), "Counted %d args", places.size() );
1152                 MessageBoxA( NULL, tmp, "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1153             }
1154 #endif // REPLACEARGS_DEBUG
1156             wchar_t** block = new wchar_t*[places.size()];
1157             int i = 0;
1158             for ( std::vector<int>::iterator it = places.begin(); it != places.end(); it++ )
1159             {
1160                 block[i++] = &lineDup[*it];
1161             }
1162             parsed = block;
1163             numArgs = places.size();
1164         }
1165 #endif // REPLACEARGS_ANSI
1167         if ( parsed )
1168         {
1169             std::vector<wchar_t*>expandedArgs;
1170             if ( numArgs > 0 )
1171             {
1172                 expandedArgs.push_back( parsed[0] );
1173             }
1175             for ( int i1 = 1; i1 < numArgs; i1++ )
1176             {
1177                 bool wildcarded = (wcschr(parsed[i1], L'?') != NULL) || (wcschr(parsed[i1], L'*') != NULL);
1178                 wildcarded &= parsed[i1][0] != L'"';
1179                 wildcarded &= parsed[i1][0] != L'-';
1180                 if ( wildcarded )
1181                 {
1182 #ifdef REPLACEARGS_ANSI
1183                     WIN32_FIND_DATAA data = {0};
1184 #else
1185                     WIN32_FIND_DATAW data = {0};
1186 #endif // REPLACEARGS_ANSI
1188                     int baseLen = wcslen(parsed[i1]) + 2;
1189                     wchar_t* base = new wchar_t[baseLen];
1190                     wcsncpy( base, parsed[i1], baseLen );
1191                     wchar_t* last = wcsrchr( base, L'\\' );
1192                     if ( last )
1193                     {
1194                         last[1] = 0;
1195                     }
1196                     else
1197                     {
1198                         base[0] = 0;
1199                     }
1200                     baseLen = wcslen( base );
1202 #ifdef REPLACEARGS_ANSI
1203                     char target[MAX_PATH];
1204                     if ( WideCharToMultiByte( CP_ACP, 0, parsed[i1], -1, target, sizeof(target), NULL, NULL) )
1205                     {
1206                         HANDLE hf = FindFirstFileA( target, &data );
1207 #else
1208                         HANDLE hf = FindFirstFileW( parsed[i1], &data );
1209 #endif // REPLACEARGS_ANSI
1210                         if ( hf != INVALID_HANDLE_VALUE )
1211                         {
1212                             BOOL found = TRUE;
1213                             do
1214                             {
1215 #ifdef REPLACEARGS_ANSI
1216                                 int howMany = MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, NULL, 0 );
1217                                 if ( howMany > 0 )
1218                                 {
1219                                     howMany += baseLen;
1220                                     wchar_t* tmp = new wchar_t[howMany + 1];
1221                                     wcsncpy( tmp, base, howMany + 1 );
1222                                     MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, tmp + baseLen, howMany + 1 - baseLen );
1223                                     expandedArgs.push_back( tmp );
1224                                     found = FindNextFileA( hf, &data );
1225                                 }
1226 #else
1227                                 int howMany = wcslen(data.cFileName) + baseLen;
1228                                 wchar_t* tmp = new wchar_t[howMany + 1];
1229                                 wcsncpy( tmp, base, howMany + 1 );
1230                                 wcsncat( tmp, data.cFileName, howMany + 1 );
1231                                 expandedArgs.push_back( tmp );
1232                                 found = FindNextFileW( hf, &data );
1233 #endif // REPLACEARGS_ANSI
1234                             } while ( found );
1236                             FindClose( hf );
1237                         }
1238                         else
1239                         {
1240                             expandedArgs.push_back( parsed[i1] );
1241                         }
1242 #ifdef REPLACEARGS_ANSI
1243                     }
1244 #endif // REPLACEARGS_ANSI
1246                     delete[] base;
1247                 }
1248                 else
1249                 {
1250                     expandedArgs.push_back( parsed[i1] );
1251                 }
1252             }
1254             {
1255                 wchar_t** block = new wchar_t*[expandedArgs.size()];
1256                 int iz = 0;
1257                 for ( std::vector<wchar_t*>::iterator it = expandedArgs.begin(); it != expandedArgs.end(); it++ )
1258                 {
1259                     block[iz++] = *it;
1260                 }
1261                 parsed = block;
1262                 numArgs = expandedArgs.size();
1263             }
1265             std::vector<gchar*> newArgs;
1266             for ( int i = 0; i < numArgs; i++ )
1267             {
1268                 gchar* replacement = g_utf16_to_utf8( (gunichar2*)parsed[i], -1, NULL, NULL, NULL );
1269                 if ( replacement )
1270                 {
1271 #ifdef REPLACEARGS_DEBUG
1272                     gchar *safe2 = Inkscape::IO::sanitizeString(replacement);
1274                     if ( safe2 )
1275                     {
1276                         {
1277                             char tmp[1024];
1278                             snprintf( tmp, sizeof(tmp), "    [%2d] = '%s'", i, safe2 );
1279                             MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1280                         }
1281                         g_free( safe2 );
1282                     }
1283 #endif // REPLACEARGS_DEBUG
1285                     newArgs.push_back( replacement );
1286                 }
1287                 else
1288                 {
1289                     newArgs.push_back( blankParam );
1290                 }
1291             }
1293             // Now push our munged params to be the new argv and argc
1294             {
1295                 char** block = new char*[newArgs.size()];
1296                 int iz = 0;
1297                 for ( std::vector<char*>::iterator it = newArgs.begin(); it != newArgs.end(); it++ )
1298                 {
1299                     block[iz++] = *it;
1300                 }
1301                 argv = block;
1302                 argc = newArgs.size();
1303                 worked = true;
1304             }
1305         }
1306 #ifdef REPLACEARGS_DEBUG
1307         else
1308         {
1309             MessageBoxA( NULL, "Unable to process command-line", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1310         }
1311 #endif // REPLACEARGS_DEBUG
1312     }
1313 #ifdef REPLACEARGS_DEBUG
1314     else
1315     {
1316         {
1317             MessageBoxA( NULL,  "Unable to fetch result from GetCommandLineW()", "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1318         }
1320         char* line2 = GetCommandLineA();
1321         if ( line2 )
1322         {
1323             gchar *safe = Inkscape::IO::sanitizeString(line2);
1324             {
1325                 {
1326                     char tmp[strlen(safe) + 32];
1327                     snprintf( tmp, sizeof(tmp), "GetCommandLineA() = '%s'", safe );
1328                     MessageBoxA( NULL, tmp, "GetCommandLineA", MB_OK | MB_ICONINFORMATION );
1329                 }
1330             }
1331         }
1332         else
1333         {
1334             MessageBoxA( NULL, "Unable to fetch result from GetCommandLineA()", "GetCommandLineA", MB_OK | MB_ICONINFORMATION );
1335         }
1336     }
1337 #endif // REPLACEARGS_DEBUG
1339     return worked;
1341 #endif // WIN32
1343 static GSList *
1344 sp_process_args(poptContext ctx)
1346     GSList *fl = NULL;
1348     gint a;
1349     while ((a = poptGetNextOpt(ctx)) >= 0) {
1350         switch (a) {
1351             case SP_ARG_FILE: {
1352                 gchar const *fn = poptGetOptArg(ctx);
1353                 if (fn != NULL) {
1354                     fl = g_slist_append(fl, g_strdup(fn));
1355                 }
1356                 break;
1357             }
1358             case SP_ARG_VERSION: {
1359                 printf("Inkscape %s (%s)\n", INKSCAPE_VERSION, __DATE__);
1360                 exit(0);
1361                 break;
1362             }
1363             case SP_ARG_EXTENSIONDIR: {
1364                 printf("%s\n", INKSCAPE_EXTENSIONDIR);
1365                 exit(0);
1366                 break;
1367             }
1368             default: {
1369                 break;
1370             }
1371         }
1372     }
1374     gchar const ** const args = poptGetArgs(ctx);
1375     if (args != NULL) {
1376         for (unsigned i = 0; args[i] != NULL; i++) {
1377             fl = g_slist_append(fl, g_strdup(args[i]));
1378         }
1379     }
1381     return fl;
1385 /*
1386   Local Variables:
1387   mode:c++
1388   c-file-style:"stroustrup"
1389   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
1390   indent-tabs-mode:nil
1391   fill-column:99
1392   End:
1393 */
1394 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :