Code

removed obsolete -G option from main.cpp and therefore from '--help' output
[inkscape.git] / src / main.cpp
1 #define __MAIN_C__
3 /** \file
4  * Inkscape - an ambitious vector drawing program
5  *
6  * Authors:
7  *   Lauris Kaplinski <lauris@kaplinski.com>
8  *   Frank Felfe <innerspace@iname.com>
9  *   Davide Puricelli <evo@debian.org>
10  *   Mitsuru Oka <oka326@parkcity.ne.jp>
11  *   Masatake YAMATO  <jet@gyve.org>
12  *   F.J.Franklin <F.J.Franklin@sheffield.ac.uk>
13  *   Michael Meeks <michael@helixcode.com>
14  *   Chema Celorio <chema@celorio.com>
15  *   Pawel Palucha
16  *   Bryce Harrington <bryce@bryceharrington.com>
17  * ... and various people who have worked with various projects
18  *
19  * Copyright (C) 1999-2004 authors
20  * Copyright (C) 2001-2002 Ximian, Inc.
21  *
22  * Released under GNU GPL, read the file 'COPYING' for more information
23  */
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29 #include "path-prefix.h"
31 #include <gtk/gtkmessagedialog.h>
33 #ifdef HAVE_IEEEFP_H
34 #include <ieeefp.h>
35 #endif
36 #include <string.h>
37 #include <locale.h>
39 #include <popt.h>
40 #ifndef POPT_TABLEEND
41 #define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL }
42 #endif /* Not def: POPT_TABLEEND */
44 #include <libxml/tree.h>
45 #include <glib-object.h>
46 #include <gtk/gtkmain.h>
47 #include <gtk/gtksignal.h>
48 #include <gtk/gtkwindow.h>
49 #include <gtk/gtkbox.h>
51 #include <gtk/gtkmain.h>
53 #include "gc-core.h"
55 #include "macros.h"
56 #include "file.h"
57 #include "document.h"
58 #include "sp-object.h"
59 #include "interface.h"
60 #include "print.h"
61 #include "slideshow.h"
62 #include "color.h"
63 #include "sp-item.h"
64 #include "sp-root.h"
65 #include "unit-constants.h"
67 #include "svg/svg.h"
68 #include "svg/svg-color.h"
69 #include "svg/stringstream.h"
71 #include "inkscape-private.h"
72 #include "inkscape-stock.h"
73 #include "inkscape_version.h"
75 #include "sp-namedview.h"
76 #include "sp-guide.h"
77 #include "sp-object-repr.h"
78 #include "xml/repr.h"
80 #include "io/sys.h"
82 #include "debug/logger.h"
84 #include "helper/png-write.h"
86 #include <extension/extension.h>
87 #include <extension/system.h>
88 #include <extension/db.h>
89 #include <extension/output.h>
91 #ifdef WIN32
92 //#define REPLACEARGS_ANSI
93 //#define REPLACEARGS_DEBUG
95 #include "registrytool.h"
97 #include "extension/internal/win32.h"
98 using Inkscape::Extension::Internal::PrintWin32;
100 #endif // WIN32
102 #include "extension/init.h"
104 #include <glibmm/i18n.h>
105 #include <gtkmm/main.h>
107 #ifndef HAVE_BIND_TEXTDOMAIN_CODESET
108 #define bind_textdomain_codeset(p,c)
109 #endif
111 #include "application/application.h"
113 enum {
114     SP_ARG_NONE,
115     SP_ARG_NOGUI,
116     SP_ARG_GUI,
117     SP_ARG_FILE,
118     SP_ARG_PRINT,
119     SP_ARG_EXPORT_PNG,
120     SP_ARG_EXPORT_DPI,
121     SP_ARG_EXPORT_AREA,
122     SP_ARG_EXPORT_AREA_DRAWING,
123     SP_ARG_EXPORT_AREA_CANVAS,
124     SP_ARG_EXPORT_AREA_SNAP,
125     SP_ARG_EXPORT_WIDTH,
126     SP_ARG_EXPORT_HEIGHT,
127     SP_ARG_EXPORT_ID,
128     SP_ARG_EXPORT_ID_ONLY,
129     SP_ARG_EXPORT_USE_HINTS,
130     SP_ARG_EXPORT_BACKGROUND,
131     SP_ARG_EXPORT_BACKGROUND_OPACITY,
132     SP_ARG_EXPORT_SVG,
133     SP_ARG_EXPORT_PS,
134     SP_ARG_EXPORT_EPS,
135     SP_ARG_EXPORT_PDF,
136     SP_ARG_EXPORT_TEXT_TO_PATH,
137     SP_ARG_EXPORT_BBOX_PAGE,
138     SP_ARG_EXTENSIONDIR,
139     SP_ARG_SLIDESHOW,
140     SP_ARG_QUERY_X,
141     SP_ARG_QUERY_Y,
142     SP_ARG_QUERY_WIDTH,
143     SP_ARG_QUERY_HEIGHT,
144     SP_ARG_QUERY_ID,
145     SP_ARG_VERSION,
146     SP_ARG_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_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-bbox-page", 'B',
314      POPT_ARG_NONE, &sp_export_bbox_page, SP_ARG_EXPORT_BBOX_PAGE,
315      N_("Export files with the bounding box set to the page size (EPS)"),
316      NULL},
318     {"query-x", 'X',
319      POPT_ARG_NONE, &sp_query_x, SP_ARG_QUERY_X,
320      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
321      N_("Query the X coordinate of the drawing or, if specified, of the object with --query-id"),
322      NULL},
324     {"query-y", 'Y',
325      POPT_ARG_NONE, &sp_query_y, SP_ARG_QUERY_Y,
326      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
327      N_("Query the Y coordinate of the drawing or, if specified, of the object with --query-id"),
328      NULL},
330     {"query-width", 'W',
331      POPT_ARG_NONE, &sp_query_width, SP_ARG_QUERY_WIDTH,
332      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
333      N_("Query the width of the drawing or, if specified, of the object with --query-id"),
334      NULL},
336     {"query-height", 'H',
337      POPT_ARG_NONE, &sp_query_height, SP_ARG_QUERY_HEIGHT,
338      // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
339      N_("Query the height of the drawing or, if specified, of the object with --query-id"),
340      NULL},
342     {"query-id", 'I',
343      POPT_ARG_STRING, &sp_query_id, SP_ARG_QUERY_ID,
344      N_("The ID of the object whose dimensions are queried"),
345      N_("ID")},
347     {"extension-directory", 'x',
348      POPT_ARG_NONE, NULL, SP_ARG_EXTENSIONDIR,
349      // TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory
350      N_("Print out the extension directory and exit"),
351      NULL},
353     {"slideshow", 's',
354      POPT_ARG_NONE, &sp_global_slideshow, SP_ARG_SLIDESHOW,
355      N_("Show given files one-by-one, switch to next on any key/mouse event"),
356      NULL},
358     {"vacuum-defs", 0,
359      POPT_ARG_NONE, &sp_vacuum_defs, SP_ARG_VACUUM_DEFS,
360      N_("Remove unused definitions from the defs section(s) of the document"),
361      NULL},
363     POPT_AUTOHELP POPT_TABLEEND
364 };
366 static bool needToRecodeParams = true;
367 gchar* blankParam = "";
369 int
370 main(int argc, char **argv)
372 #ifdef HAVE_FPSETMASK
373     /* This is inherited from Sodipodi code, where it was in #ifdef __FreeBSD__.  It's probably
374        safe to remove: the default mask is already 0 in C99, and in current FreeBSD according to
375        the fenv man page on www.freebsd.org, and in glibc according to (libc)FP Exceptions. */
376     fpsetmask(fpgetmask() & ~(FP_X_DZ | FP_X_INV));
377 #endif
379 #ifdef ENABLE_NLS
380 #ifdef WIN32
381     RegistryTool rt;
382     rt.setPathInfo();
383     gchar *pathBuf = g_strconcat(g_path_get_dirname(argv[0]), "\\", PACKAGE_LOCALE_DIR, NULL);
384     bindtextdomain(GETTEXT_PACKAGE, pathBuf);
385     g_free(pathBuf);
386 #else
387 #ifdef ENABLE_BINRELOC
388     bindtextdomain(GETTEXT_PACKAGE, BR_LOCALEDIR(""));
389 #else
390     bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
391 #endif
392 #endif
393 #endif
395     bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
397 #ifdef ENABLE_NLS
398     textdomain(GETTEXT_PACKAGE);
399 #endif
401     LIBXML_TEST_VERSION
403     Inkscape::GC::init();
405     Inkscape::Debug::Logger::init();
407     gboolean use_gui;
408 #ifndef WIN32
409     use_gui = (getenv("DISPLAY") != NULL);
410 #else
411     /*
412       Set the current directory to the directory of the
413       executable.  This seems redundant, but is needed for
414       when inkscape.exe is executed from another directory.
415       We use relative paths on win32.
416       HKCR\svgfile\shell\open\command is a good example
417     */
418     /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
419     char *homedir = g_path_get_dirname(argv[0]);
420     SetCurrentDirectory(homedir);
421     g_free(homedir);
423     use_gui = TRUE;
424 #endif
425     /* Test whether with/without GUI is forced */
426     for (int i = 1; i < argc; i++) {
427         if (!strcmp(argv[i], "-z")
428             || !strcmp(argv[i], "--without-gui")
429             || !strcmp(argv[i], "-p")
430             || !strncmp(argv[i], "--print", 7)
431             || !strcmp(argv[i], "-e")
432             || !strncmp(argv[i], "--export-png", 12)
433             || !strcmp(argv[i], "-l")
434             || !strncmp(argv[i], "--export-plain-svg", 12)
435             || !strcmp(argv[i], "-i")
436             || !strncmp(argv[i], "--export-area-drawing", 21)
437             || !strcmp(argv[i], "-D")
438             || !strncmp(argv[i], "--export-area-canvas", 20)
439             || !strcmp(argv[i], "-C")
440             || !strncmp(argv[i], "--export-id", 12)
441             || !strcmp(argv[i], "-P")
442             || !strncmp(argv[i], "--export-ps", 11)
443             || !strcmp(argv[i], "-E")
444             || !strncmp(argv[i], "--export-eps", 12)
445             || !strcmp(argv[i], "-A")
446             || !strncmp(argv[i], "--export-pdf", 12)
447             || !strcmp(argv[i], "-W")
448             || !strncmp(argv[i], "--query-width", 13)
449             || !strcmp(argv[i], "-H")
450             || !strncmp(argv[i], "--query-height", 14)
451             || !strcmp(argv[i], "-X")
452             || !strncmp(argv[i], "--query-x", 13)
453             || !strcmp(argv[i], "-Y")
454             || !strncmp(argv[i], "--query-y", 14)
455             || !strcmp(argv[i], "--vacuum-defs")
456            )
457         {
458             /* main_console handles any exports -- not the gui */
459             use_gui = FALSE;
460             break;
461         } else if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--with-gui")) {
462             use_gui = TRUE;
463             break;
464         }
465     }
467 #ifdef WIN32
468 #ifndef REPLACEARGS_ANSI
469     if ( PrintWin32::is_os_wide() )
470 #endif // REPLACEARGS_ANSI
471     {
472         // If the call fails, we'll need to convert charsets
473         needToRecodeParams = !replaceArgs( argc, argv );
474     }
475 #endif // WIN32
477     /// \todo  Should this be a static object (see inkscape.cpp)?
478     Inkscape::NSApplication::Application app(argc, argv, use_gui, sp_new_gui);
480     return app.run();
483 void fixupSingleFilename( gchar **orig, gchar **spare )
485     if ( orig && *orig && **orig ) {
486         GError *error = NULL;
487         gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(*orig, -1, NULL, NULL, &error);
488         if ( newFileName )
489         {
490             *orig = newFileName;
491             if ( spare ) {
492                 *spare = newFileName;
493             }
494 //             g_message("Set a replacement fixup");
495         }
496     }
499 GSList *fixupFilenameEncoding( GSList* fl )
501     GSList *newFl = NULL;
502     while ( fl ) {
503         gchar *fn = static_cast<gchar*>(fl->data);
504         fl = g_slist_remove( fl, fl->data );
505         gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(fn, -1, NULL, NULL, NULL);
506         if ( newFileName ) {
508             if ( 0 )
509             {
510                 gchar *safeFn = Inkscape::IO::sanitizeString(fn);
511                 gchar *safeNewFn = Inkscape::IO::sanitizeString(newFileName);
512                 GtkWidget *w = gtk_message_dialog_new( NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
513                                                        "Note: Converted '%s' to '%s'", safeFn, safeNewFn );
514                 gtk_dialog_run (GTK_DIALOG (w));
515                 gtk_widget_destroy (w);
516                 g_free(safeNewFn);
517                 g_free(safeFn);
518             }
520             g_free( fn );
521             fn = newFileName;
522             newFileName = 0;
523         }
524         else
525             if ( 0 )
526         {
527             gchar *safeFn = Inkscape::IO::sanitizeString(fn);
528             GtkWidget *w = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "Error: Unable to convert '%s'", safeFn );
529             gtk_dialog_run (GTK_DIALOG (w));
530             gtk_widget_destroy (w);
531             g_free(safeFn);
532         }
533         newFl = g_slist_append( newFl, fn );
534     }
535     return newFl;
538 int sp_common_main( int argc, char const **argv, GSList **flDest )
540     /// \todo fixme: Move these to some centralized location (Lauris)
541     sp_object_type_register("sodipodi:namedview", SP_TYPE_NAMEDVIEW);
542     sp_object_type_register("sodipodi:guide", SP_TYPE_GUIDE);
545     // temporarily switch gettext encoding to locale, so that help messages can be output properly
546     gchar const *charset;
547     g_get_charset(&charset);
549     bind_textdomain_codeset(GETTEXT_PACKAGE, charset);
551     poptContext ctx = poptGetContext(NULL, argc, argv, options, 0);
552     poptSetOtherOptionHelp(ctx, _("[OPTIONS...] [FILE...]\n\nAvailable options:"));
553     g_return_val_if_fail(ctx != NULL, 1);
555     /* Collect own arguments */
556     GSList *fl = sp_process_args(ctx);
557     poptFreeContext(ctx);
559     // now switch gettext back to UTF-8 (for GUI)
560     bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
562     // Now let's see if the file list still holds up
563     if ( needToRecodeParams )
564     {
565         fl = fixupFilenameEncoding( fl );
566     }
568     // Check the globals for filename-fixup
569     if ( needToRecodeParams )
570     {
571         fixupSingleFilename( &sp_export_png, &sp_export_png_utf8 );
572         fixupSingleFilename( &sp_export_svg, &sp_export_svg_utf8 );
573         fixupSingleFilename( &sp_global_printer, &sp_global_printer_utf8 );
574     }
575     else
576     {
577         if ( sp_export_png )
578             sp_export_png_utf8 = g_strdup( sp_export_png );
579         if ( sp_export_svg )
580             sp_export_svg_utf8 = g_strdup( sp_export_svg );
581         if ( sp_global_printer )
582             sp_global_printer_utf8 = g_strdup( sp_global_printer );
583     }
585     // Return the list if wanted, else free it up.
586     if ( flDest ) {
587         *flDest = fl;
588         fl = 0;
589     } else {
590         while ( fl ) {
591             g_free( fl->data );
592             fl = g_slist_remove( fl, fl->data );
593         }
594     }
595     return 0;
598 int
599 sp_main_gui(int argc, char const **argv)
601     Gtk::Main main_instance (&argc, const_cast<char ***>(&argv));
603     GSList *fl = NULL;
604     int retVal = sp_common_main( argc, argv, &fl );
605     g_return_val_if_fail(retVal == 0, 1);
607     inkscape_gtk_stock_init();
609     /* Set default icon */
610     gchar *filename = (gchar *) g_build_filename (INKSCAPE_APPICONDIR, "inkscape.png", NULL);
611     if (Inkscape::IO::file_test(filename, (GFileTest)(G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK))) {
612         gtk_window_set_default_icon_from_file(filename, NULL);
613     }
614     g_free (filename);
615     filename = 0;
617     if (!sp_global_slideshow) {
618         gboolean create_new = TRUE;
620         /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
621         inkscape_application_init(argv[0], true);
623         while (fl) {
624             if (sp_file_open((gchar *)fl->data,NULL)) {
625                 create_new=FALSE;
626             }
627             fl = g_slist_remove(fl, fl->data);
628         }
629         if (create_new) {
630             sp_file_new_default();
631         }
632     } else {
633         if (fl) {
634             GtkWidget *ss;
635             /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
636             inkscape_application_init(argv[0], true);
637             ss = sp_slideshow_new(fl);
638             if (ss) gtk_widget_show(ss);
639         } else {
640             g_warning ("No slides to display");
641             exit(0);
642         }
643     }
645     main_instance.run();
647 #ifdef WIN32
648     //We might not need anything here
649     //sp_win32_finish(); <-- this is a NOP func
650 #endif
652     return 0;
655 int
656 sp_main_console(int argc, char const **argv)
658     /* We are started in text mode */
660     /* Do this g_type_init(), so that we can use Xft/Freetype2 (Pango)
661      * in a non-Gtk environment.  Used in libnrtype's
662      * FontInstance.cpp and FontFactory.cpp.
663      * http://mail.gnome.org/archives/gtk-list/2003-December/msg00063.html
664      */
665     g_type_init();
666     char **argv2 = const_cast<char **>(argv);
667     gtk_init_check( &argc, &argv2 );
668     //setlocale(LC_ALL, "");
670     GSList *fl = NULL;
671     int retVal = sp_common_main( argc, argv, &fl );
672     g_return_val_if_fail(retVal == 0, 1);
674     if (fl == NULL) {
675         g_print("Nothing to do!\n");
676         exit(0);
677     }
679     inkscape_application_init(argv[0], false);
681     while (fl) {
682         SPDocument *doc;
684         doc = Inkscape::Extension::open(NULL, (gchar *)fl->data);
685         if (doc == NULL) {
686             doc = Inkscape::Extension::open(Inkscape::Extension::db.get(SP_MODULE_KEY_INPUT_SVG), (gchar *)fl->data);
687         }
688         if (doc == NULL) {
689             g_warning("Specified document %s cannot be opened (is it valid SVG file?)", (gchar *) fl->data);
690         } else {
691             if (sp_vacuum_defs) {
692                 vacuum_document(doc);
693             }
694             if (sp_vacuum_defs && !sp_export_svg) {
695                 // save under the name given in the command line
696                 sp_repr_save_file(doc->rdoc, (gchar *)fl->data, SP_SVG_NS_URI);
697             }
698             if (sp_global_printer) {
699                 sp_print_document_to_file(doc, sp_global_printer);
700             }
701             if (sp_export_png || sp_export_id || sp_export_area_drawing) {
702                 sp_do_export_png(doc);
703             }
704             if (sp_export_svg) {
705                 Inkscape::XML::Document *rdoc;
706                 Inkscape::XML::Node *repr;
707                 rdoc = sp_repr_document_new("svg:svg");
708                 repr = rdoc->root();
709                 repr = sp_document_root(doc)->updateRepr(repr, SP_OBJECT_WRITE_BUILD);
710                 sp_repr_save_file(repr->document(), sp_export_svg, SP_SVG_NS_URI);
711             }
712             if (sp_export_ps) {
713                 do_export_ps(doc, sp_export_ps, "image/x-postscript");
714             }
715             if (sp_export_eps) {
716                 do_export_ps(doc, sp_export_eps, "image/x-e-postscript");
717             }
718             if (sp_export_pdf) {
719                 do_export_pdf(doc, sp_export_pdf, "application/pdf");
720             }
721             if (sp_query_width || sp_query_height) {
722                 do_query_dimension (doc, true, sp_query_width? NR::X : NR::Y, sp_query_id);
723             } else if (sp_query_x || sp_query_y) {
724                 do_query_dimension (doc, false, sp_query_x? NR::X : NR::Y, sp_query_id);
725             }
726         }
727         fl = g_slist_remove(fl, fl->data);
728     }
730     inkscape_unref();
732     return 0;
735 static void
736 do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gchar *id)
738     SPObject *o = NULL;
740     if (id) {
741         o = doc->getObjectById(id);
742         if (o) {
743             if (!SP_IS_ITEM (o)) {
744                 g_warning("Object with id=\"%s\" is not a visible item. Cannot query dimensions.", id);
745                 return;
746             }
747         } else {
748             g_warning("Object with id=\"%s\" is not found. Cannot query dimensions.", id);
749             return;
750         }
751     } else {
752         o = SP_DOCUMENT_ROOT(doc);
753     }
755     if (o) {
756         sp_document_ensure_up_to_date (doc);
757         SPItem *item = ((SPItem *) o);
758         NR::Rect area = item->invokeBbox(sp_item_i2doc_affine(item)); // "true" SVG bbox for scripting
760         Inkscape::SVGOStringStream os;
761         if (extent) {
762             os << area.extent(axis);
763         } else {
764             os << area.min()[axis];
765         }
766         g_print ("%s", os.str().c_str());
767     }
771 static void
772 sp_do_export_png(SPDocument *doc)
774     const gchar *filename = NULL;
775     gdouble dpi = 0.0;
777     if (sp_export_use_hints && (!sp_export_id && !sp_export_area_drawing)) {
778         g_warning ("--export-use-hints can only be used with --export-id or --export-area-drawing; ignored.");
779     }
781     GSList *items = NULL;
783     NRRect area;
784     if (sp_export_id || sp_export_area_drawing) {
786         SPObject *o = NULL;
787         SPObject *o_area = NULL;
788         if (sp_export_id && sp_export_area_drawing) {
789             o = doc->getObjectById(sp_export_id);
790             o_area = SP_DOCUMENT_ROOT (doc);
791         } else if (sp_export_id) {
792             o = doc->getObjectById(sp_export_id);
793             o_area = o;
794         } else if (sp_export_area_drawing) {
795             o = SP_DOCUMENT_ROOT (doc);
796             o_area = o;
797         } 
799         if (o) {
800             if (!SP_IS_ITEM (o)) {
801                 g_warning("Object with id=\"%s\" is not a visible item. Nothing exported.", sp_export_id);
802                 return;
803             }
805             items = g_slist_prepend (items, SP_ITEM(o));
807             if (sp_export_id_only) {
808                 g_print("Exporting only object with id=\"%s\"; all other objects hidden\n", sp_export_id);
809             }
811             if (sp_export_use_hints) {
813                 // retrieve export filename hint
814                 const gchar *fn_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-filename");
815                 if (fn_hint) {
816                     if (sp_export_png) {
817                         g_warning ("Using export filename from the command line (--export-png). Filename hint %s is ignored.", fn_hint);
818                         filename = sp_export_png;
819                     } else {
820                         filename = fn_hint;
821                     }
822                 } else {
823                     g_warning ("Export filename hint not found for the object.");
824                     filename = sp_export_png;
825                 }
827                 // retrieve export dpi hints
828                 const gchar *dpi_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-xdpi"); // only xdpi, ydpi is always the same now
829                 if (dpi_hint) {
830                     if (sp_export_dpi || sp_export_width || sp_export_height) {
831                         g_warning ("Using bitmap dimensions from the command line (--export-dpi, --export-width, or --export-height). DPI hint %s is ignored.", dpi_hint);
832                     } else {
833                         dpi = atof(dpi_hint);
834                     }
835                 } else {
836                     g_warning ("Export DPI hint not found for the object.");
837                 }
839             }
841             // write object bbox to area
842             sp_document_ensure_up_to_date (doc);
843             sp_item_invoke_bbox((SPItem *) o_area, &area, sp_item_i2r_affine((SPItem *) o_area), TRUE);
844         } else {
845             g_warning("Object with id=\"%s\" was not found in the document. Nothing exported.", sp_export_id);
846             return;
847         }
848     }
849     
850     if (sp_export_area) {
851         /* Try to parse area (given in SVG pixels) */
852         if (!sscanf(sp_export_area, "%lg:%lg:%lg:%lg", &area.x0, &area.y0, &area.x1, &area.y1) == 4) {
853             g_warning("Cannot parse export area '%s'; use 'x0:y0:x1:y1'. Nothing exported.", sp_export_area);
854             return;
855         }
856         if ((area.x0 >= area.x1) || (area.y0 >= area.y1)) {
857             g_warning("Export area '%s' has negative width or height. Nothing exported.", sp_export_area);
858             return;
859         }
860     } else if (sp_export_area_canvas || !(sp_export_id || sp_export_area_drawing)) {
861         /* Export the whole canvas */
862         sp_document_ensure_up_to_date (doc);
863         area.x0 = SP_ROOT(doc->root)->x.computed;
864         area.y0 = SP_ROOT(doc->root)->y.computed;
865         area.x1 = area.x0 + sp_document_width (doc);
866         area.y1 = area.y0 + sp_document_height (doc);
867     }
869     // set filename and dpi from options, if not yet set from the hints
870     if (!filename) {
871         if (!sp_export_png) {
872             g_warning ("No export filename given and no filename hint. Nothing exported.");
873             return;
874         }
875         filename = sp_export_png;
876     }
878     if (sp_export_dpi && dpi == 0.0) {
879         dpi = atof(sp_export_dpi);
880         if ((dpi < 0.1) || (dpi > 10000.0)) {
881             g_warning("DPI value %s out of range [0.1 - 10000.0]. Nothing exported.", sp_export_dpi);
882             return;
883         }
884         g_print("DPI: %g\n", dpi);
885     }
887     if (sp_export_area_snap) {
888         area.x0 = std::floor (area.x0);
889         area.y0 = std::floor (area.y0);
890         area.x1 = std::ceil (area.x1);
891         area.y1 = std::ceil (area.y1);
892     }
894     // default dpi
895     if (dpi == 0.0)
896         dpi = PX_PER_IN;
898     gint width = 0;
899     gint height = 0;
901     if (sp_export_width) {
902         width = atoi(sp_export_width);
903         if ((width < 1) || (width > 65536)) {
904             g_warning("Export width %d out of range (1 - 65536). Nothing exported.", width);
905             return;
906         }
907         dpi = (gdouble) width * PX_PER_IN / (area.x1 - area.x0);
908     }
910     if (sp_export_height) {
911         height = atoi(sp_export_height);
912         if ((height < 1) || (height > 65536)) {
913             g_warning("Export height %d out of range (1 - 65536). Nothing exported.", width);
914             return;
915         }
916         dpi = (gdouble) height * PX_PER_IN / (area.y1 - area.y0);
917     }
919     if (!sp_export_width) {
920         width = (gint) ((area.x1 - area.x0) * dpi / PX_PER_IN + 0.5);
921     }
923     if (!sp_export_height) {
924         height = (gint) ((area.y1 - area.y0) * dpi / PX_PER_IN + 0.5);
925     }
927     guint32 bgcolor = 0x00000000;
928     if (sp_export_background) {
929         // override the page color
930         bgcolor = sp_svg_read_color(sp_export_background, 0xffffff00);
931         bgcolor |= 0xff; // default is no opacity
932     } else {
933         // read from namedview
934         Inkscape::XML::Node *nv = sp_repr_lookup_name (doc->rroot, "sodipodi:namedview");
935         if (nv && nv->attribute("pagecolor"))
936             bgcolor = sp_svg_read_color(nv->attribute("pagecolor"), 0xffffff00);
937         if (nv && nv->attribute("inkscape:pageopacity"))
938             bgcolor |= SP_COLOR_F_TO_U(sp_repr_get_double_attribute (nv, "inkscape:pageopacity", 1.0));
939     }
941     if (sp_export_background_opacity) {
942         // override opacity
943         gfloat value;
944         if (sp_svg_number_read_f (sp_export_background_opacity, &value)) {
945             if (value > 1.0) {
946                 value = CLAMP (value, 1.0f, 255.0f);
947                 bgcolor &= (guint32) 0xffffff00;
948                 bgcolor |= (guint32) floor(value);
949             } else {
950                 value = CLAMP (value, 0.0f, 1.0f);
951                 bgcolor &= (guint32) 0xffffff00;
952                 bgcolor |= SP_COLOR_F_TO_U(value);
953             }
954         }
955     }
957     g_print("Background RRGGBBAA: %08x\n", bgcolor);
959     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);
961     g_print("Bitmap saved as: %s\n", filename);
963     if ((width >= 1) && (height >= 1) && (width < 65536) && (height < 65536)) {
964         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);
965     } else {
966         g_warning("Calculated bitmap dimensions %d %d are out of range (1 - 65535). Nothing exported.", width, height);
967     }
969     g_slist_free (items);
973 /**
974  *  Perform an export of either PS or EPS.
975  *
976  *  \param doc Document to export.
977  *  \param uri URI to export to.
978  *  \param mime MIME type to export as.
979  */
981 static void do_export_ps(SPDocument* doc, gchar const* uri, char const* mime)
983     Inkscape::Extension::DB::OutputList o;
984     Inkscape::Extension::db.get_output_list(o);
985     Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
986     while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
987         i++;
988     }
990     if (i == o.end())
991     {
992         g_warning ("Could not find an extension to export this file.");
993         return;
994     }
996     bool old_text_to_path = false;
997     bool old_bbox_page = false;
999     try {
1000         old_text_to_path = (*i)->get_param_bool("textToPath");
1001         (*i)->set_param_bool("textToPath", sp_export_text_to_path);
1002     }
1003     catch (...) {
1004         g_warning ("Could not set export-text-to-path option for this export.");
1005     }
1007     try {
1008         old_bbox_page = (*i)->get_param_bool("pageBoundingBox");
1009         (*i)->set_param_bool("pageBoundingBox", sp_export_bbox_page);
1010     }
1011     catch (...) {
1012         g_warning ("Could not set export-bbox-page option for this export.");
1013     }
1015     (*i)->save(doc, uri);
1017     try {
1018         (*i)->set_param_bool("textToPath", old_text_to_path);
1019         (*i)->set_param_bool("pageBoundingBox", old_bbox_page);
1020     }
1021     catch (...) {
1023     }
1026 /**
1027  *  Perform a PDF export
1028  *
1029  *  \param doc Document to export.
1030  *  \param uri URI to export to.
1031  *  \param mime MIME type to export as.
1032  */
1034 static void do_export_pdf(SPDocument* doc, gchar const* uri, char const* mime)
1036     Inkscape::Extension::DB::OutputList o;
1037     Inkscape::Extension::db.get_output_list(o);
1038     Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
1039     while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
1040         i++;
1041     }
1043     if (i == o.end())
1044     {
1045         g_warning ("Could not find an extension to export this file.");
1046         return;
1047     }
1049     (*i)->save(doc, uri);
1052 #ifdef WIN32
1053 bool replaceArgs( int& argc, char**& argv )
1055     bool worked = false;
1057 #ifdef REPLACEARGS_DEBUG
1058     MessageBoxA( NULL, "GetCommandLineW() getting called", "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1059 #endif // REPLACEARGS_DEBUG
1061     wchar_t* line = GetCommandLineW();
1062     if ( line )
1063     {
1064 #ifdef REPLACEARGS_DEBUG
1065         {
1066             gchar* utf8Line = g_utf16_to_utf8( (gunichar2*)line, -1, NULL, NULL, NULL );
1067             if ( utf8Line )
1068             {
1069                 gchar *safe = Inkscape::IO::sanitizeString(utf8Line);
1070                 {
1071                     char tmp[strlen(safe) + 32];
1072                     snprintf( tmp, sizeof(tmp), "GetCommandLineW() = '%s'", safe );
1073                     MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1074                 }
1075             }
1076         }
1077 #endif // REPLACEARGS_DEBUG
1079         int numArgs = 0;
1080         wchar_t** parsed = CommandLineToArgvW( line, &numArgs );
1082 #ifdef REPLACEARGS_ANSI
1083 // test code for trying things on Win95/98/ME
1084         if ( !parsed )
1085         {
1086 #ifdef REPLACEARGS_DEBUG
1087             MessageBoxA( NULL, "Unable to process command-line. Faking it", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1088 #endif // REPLACEARGS_DEBUG
1089             int lineLen = wcslen(line) + 1;
1090             wchar_t* lineDup = new wchar_t[lineLen];
1091             wcsncpy( lineDup, line, lineLen );
1093             int pos = 0;
1094             bool inQuotes = false;
1095             bool inWhitespace = true;
1096             std::vector<int> places;
1097             while ( lineDup[pos] )
1098             {
1099                 if ( inQuotes )
1100                 {
1101                     if ( lineDup[pos] == L'"' )
1102                     {
1103                         inQuotes = false;
1104                     }
1105                 }
1106                 else if ( lineDup[pos] == L'"' )
1107                 {
1108                     inQuotes = true;
1109                     inWhitespace = false;
1110                     places.push_back(pos);
1111                 }
1112                 else if ( lineDup[pos] == L' ' || lineDup[pos] == L'\t' )
1113                 {
1114                     if ( !inWhitespace )
1115                     {
1116                         inWhitespace = true;
1117                         lineDup[pos] = 0;
1118                     }
1119                 }
1120                 else if ( inWhitespace && (lineDup[pos] != L' ' && lineDup[pos] != L'\t') )
1121                 {
1122                     inWhitespace = false;
1123                     places.push_back(pos);
1124                 }
1125                 else
1126                 {
1127                     // consume
1128                 }
1129                 pos++;
1130             }
1131 #ifdef REPLACEARGS_DEBUG
1132             {
1133                 char tmp[256];
1134                 snprintf( tmp, sizeof(tmp), "Counted %d args", places.size() );
1135                 MessageBoxA( NULL, tmp, "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1136             }
1137 #endif // REPLACEARGS_DEBUG
1139             wchar_t** block = new wchar_t*[places.size()];
1140             int i = 0;
1141             for ( std::vector<int>::iterator it = places.begin(); it != places.end(); it++ )
1142             {
1143                 block[i++] = &lineDup[*it];
1144             }
1145             parsed = block;
1146             numArgs = places.size();
1147         }
1148 #endif // REPLACEARGS_ANSI
1150         if ( parsed )
1151         {
1152             std::vector<wchar_t*>expandedArgs;
1153             if ( numArgs > 0 )
1154             {
1155                 expandedArgs.push_back( parsed[0] );
1156             }
1158             for ( int i1 = 1; i1 < numArgs; i1++ )
1159             {
1160                 bool wildcarded = (wcschr(parsed[i1], L'?') != NULL) || (wcschr(parsed[i1], L'*') != NULL);
1161                 wildcarded &= parsed[i1][0] != L'"';
1162                 wildcarded &= parsed[i1][0] != L'-';
1163                 if ( wildcarded )
1164                 {
1165 #ifdef REPLACEARGS_ANSI
1166                     WIN32_FIND_DATAA data = {0};
1167 #else
1168                     WIN32_FIND_DATAW data = {0};
1169 #endif // REPLACEARGS_ANSI
1171                     int baseLen = wcslen(parsed[i1]) + 2;
1172                     wchar_t* base = new wchar_t[baseLen];
1173                     wcsncpy( base, parsed[i1], baseLen );
1174                     wchar_t* last = wcsrchr( base, L'\\' );
1175                     if ( last )
1176                     {
1177                         last[1] = 0;
1178                     }
1179                     else
1180                     {
1181                         base[0] = 0;
1182                     }
1183                     baseLen = wcslen( base );
1185 #ifdef REPLACEARGS_ANSI
1186                     char target[MAX_PATH];
1187                     if ( WideCharToMultiByte( CP_ACP, 0, parsed[i1], -1, target, sizeof(target), NULL, NULL) )
1188                     {
1189                         HANDLE hf = FindFirstFileA( target, &data );
1190 #else
1191                         HANDLE hf = FindFirstFileW( parsed[i1], &data );
1192 #endif // REPLACEARGS_ANSI
1193                         if ( hf != INVALID_HANDLE_VALUE )
1194                         {
1195                             BOOL found = TRUE;
1196                             do
1197                             {
1198 #ifdef REPLACEARGS_ANSI
1199                                 int howMany = MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, NULL, 0 );
1200                                 if ( howMany > 0 )
1201                                 {
1202                                     howMany += baseLen;
1203                                     wchar_t* tmp = new wchar_t[howMany + 1];
1204                                     wcsncpy( tmp, base, howMany + 1 );
1205                                     MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, tmp + baseLen, howMany + 1 - baseLen );
1206                                     expandedArgs.push_back( tmp );
1207                                     found = FindNextFileA( hf, &data );
1208                                 }
1209 #else
1210                                 int howMany = wcslen(data.cFileName) + baseLen;
1211                                 wchar_t* tmp = new wchar_t[howMany + 1];
1212                                 wcsncpy( tmp, base, howMany + 1 );
1213                                 wcsncat( tmp, data.cFileName, howMany + 1 );
1214                                 expandedArgs.push_back( tmp );
1215                                 found = FindNextFileW( hf, &data );
1216 #endif // REPLACEARGS_ANSI
1217                             } while ( found );
1219                             FindClose( hf );
1220                         }
1221                         else
1222                         {
1223                             expandedArgs.push_back( parsed[i1] );
1224                         }
1225 #ifdef REPLACEARGS_ANSI
1226                     }
1227 #endif // REPLACEARGS_ANSI
1229                     delete[] base;
1230                 }
1231                 else
1232                 {
1233                     expandedArgs.push_back( parsed[i1] );
1234                 }
1235             }
1237             {
1238                 wchar_t** block = new wchar_t*[expandedArgs.size()];
1239                 int iz = 0;
1240                 for ( std::vector<wchar_t*>::iterator it = expandedArgs.begin(); it != expandedArgs.end(); it++ )
1241                 {
1242                     block[iz++] = *it;
1243                 }
1244                 parsed = block;
1245                 numArgs = expandedArgs.size();
1246             }
1248             std::vector<gchar*> newArgs;
1249             for ( int i = 0; i < numArgs; i++ )
1250             {
1251                 gchar* replacement = g_utf16_to_utf8( (gunichar2*)parsed[i], -1, NULL, NULL, NULL );
1252                 if ( replacement )
1253                 {
1254 #ifdef REPLACEARGS_DEBUG
1255                     gchar *safe2 = Inkscape::IO::sanitizeString(replacement);
1257                     if ( safe2 )
1258                     {
1259                         {
1260                             char tmp[1024];
1261                             snprintf( tmp, sizeof(tmp), "    [%2d] = '%s'", i, safe2 );
1262                             MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1263                         }
1264                         g_free( safe2 );
1265                     }
1266 #endif // REPLACEARGS_DEBUG
1268                     newArgs.push_back( replacement );
1269                 }
1270                 else
1271                 {
1272                     newArgs.push_back( blankParam );
1273                 }
1274             }
1276             // Now push our munged params to be the new argv and argc
1277             {
1278                 char** block = new char*[newArgs.size()];
1279                 int iz = 0;
1280                 for ( std::vector<char*>::iterator it = newArgs.begin(); it != newArgs.end(); it++ )
1281                 {
1282                     block[iz++] = *it;
1283                 }
1284                 argv = block;
1285                 argc = newArgs.size();
1286                 worked = true;
1287             }
1288         }
1289 #ifdef REPLACEARGS_DEBUG
1290         else
1291         {
1292             MessageBoxA( NULL, "Unable to process command-line", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1293         }
1294 #endif // REPLACEARGS_DEBUG
1295     }
1296 #ifdef REPLACEARGS_DEBUG
1297     else
1298     {
1299         {
1300             MessageBoxA( NULL,  "Unable to fetch result from GetCommandLineW()", "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1301         }
1303         char* line2 = GetCommandLineA();
1304         if ( line2 )
1305         {
1306             gchar *safe = Inkscape::IO::sanitizeString(line2);
1307             {
1308                 {
1309                     char tmp[strlen(safe) + 32];
1310                     snprintf( tmp, sizeof(tmp), "GetCommandLineA() = '%s'", safe );
1311                     MessageBoxA( NULL, tmp, "GetCommandLineA", MB_OK | MB_ICONINFORMATION );
1312                 }
1313             }
1314         }
1315         else
1316         {
1317             MessageBoxA( NULL, "Unable to fetch result from GetCommandLineA()", "GetCommandLineA", MB_OK | MB_ICONINFORMATION );
1318         }
1319     }
1320 #endif // REPLACEARGS_DEBUG
1322     return worked;
1324 #endif // WIN32
1326 static GSList *
1327 sp_process_args(poptContext ctx)
1329     GSList *fl = NULL;
1331     gint a;
1332     while ((a = poptGetNextOpt(ctx)) >= 0) {
1333         switch (a) {
1334             case SP_ARG_FILE: {
1335                 gchar const *fn = poptGetOptArg(ctx);
1336                 if (fn != NULL) {
1337                     fl = g_slist_append(fl, g_strdup(fn));
1338                 }
1339                 break;
1340             }
1341             case SP_ARG_VERSION: {
1342                 printf("Inkscape %s (%s)\n", INKSCAPE_VERSION, __DATE__);
1343                 exit(0);
1344                 break;
1345             }
1346             case SP_ARG_EXTENSIONDIR: {
1347                 printf("%s\n", INKSCAPE_EXTENSIONDIR);
1348                 exit(0);
1349                 break;
1350             }
1351             default: {
1352                 break;
1353             }
1354         }
1355     }
1357     gchar const ** const args = poptGetArgs(ctx);
1358     if (args != NULL) {
1359         for (unsigned i = 0; args[i] != NULL; i++) {
1360             fl = g_slist_append(fl, g_strdup(args[i]));
1361         }
1362     }
1364     return fl;
1368 /*
1369   Local Variables:
1370   mode:c++
1371   c-file-style:"stroustrup"
1372   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
1373   indent-tabs-mode:nil
1374   fill-column:99
1375   End:
1376 */
1377 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :