Code

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