Code

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