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