Code

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