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 // Allow the user to override the locale directory by setting
400 // the environment variable INKSCAPE_LOCALEDIR.
401 char *inkscape_localedir = getenv("INKSCAPE_LOCALEDIR");
402 if (inkscape_localedir != NULL) {
403 bindtextdomain(GETTEXT_PACKAGE, inkscape_localedir);
404 }
405 #endif
407 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
409 #ifdef ENABLE_NLS
410 textdomain(GETTEXT_PACKAGE);
411 #endif
413 LIBXML_TEST_VERSION
415 Inkscape::GC::init();
417 Inkscape::Debug::Logger::init();
419 gboolean use_gui;
420 #ifndef WIN32
421 use_gui = (getenv("DISPLAY") != NULL);
422 #else
423 /*
424 Set the current directory to the directory of the
425 executable. This seems redundant, but is needed for
426 when inkscape.exe is executed from another directory.
427 We use relative paths on win32.
428 HKCR\svgfile\shell\open\command is a good example
429 */
430 /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
431 char *homedir = g_path_get_dirname(argv[0]);
432 SetCurrentDirectory(homedir);
433 g_free(homedir);
435 use_gui = TRUE;
436 #endif
437 /* Test whether with/without GUI is forced */
438 for (int i = 1; i < argc; i++) {
439 if (!strcmp(argv[i], "-z")
440 || !strcmp(argv[i], "--without-gui")
441 || !strcmp(argv[i], "-p")
442 || !strncmp(argv[i], "--print", 7)
443 || !strcmp(argv[i], "-e")
444 || !strncmp(argv[i], "--export-png", 12)
445 || !strcmp(argv[i], "-l")
446 || !strncmp(argv[i], "--export-plain-svg", 12)
447 || !strcmp(argv[i], "-i")
448 || !strncmp(argv[i], "--export-area-drawing", 21)
449 || !strcmp(argv[i], "-D")
450 || !strncmp(argv[i], "--export-area-canvas", 20)
451 || !strcmp(argv[i], "-C")
452 || !strncmp(argv[i], "--export-id", 12)
453 || !strcmp(argv[i], "-P")
454 || !strncmp(argv[i], "--export-ps", 11)
455 || !strcmp(argv[i], "-E")
456 || !strncmp(argv[i], "--export-eps", 12)
457 || !strcmp(argv[i], "-A")
458 || !strncmp(argv[i], "--export-pdf", 12)
459 || !strcmp(argv[i], "-W")
460 || !strncmp(argv[i], "--query-width", 13)
461 || !strcmp(argv[i], "-H")
462 || !strncmp(argv[i], "--query-height", 14)
463 || !strcmp(argv[i], "-X")
464 || !strncmp(argv[i], "--query-x", 13)
465 || !strcmp(argv[i], "-Y")
466 || !strncmp(argv[i], "--query-y", 14)
467 || !strcmp(argv[i], "--vacuum-defs")
468 )
469 {
470 /* main_console handles any exports -- not the gui */
471 use_gui = FALSE;
472 break;
473 } else if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--with-gui")) {
474 use_gui = TRUE;
475 break;
476 }
477 }
479 #ifdef WIN32
480 #ifndef REPLACEARGS_ANSI
481 if ( PrintWin32::is_os_wide() )
482 #endif // REPLACEARGS_ANSI
483 {
484 // If the call fails, we'll need to convert charsets
485 needToRecodeParams = !replaceArgs( argc, argv );
486 }
487 #endif // WIN32
489 /// \todo Should this be a static object (see inkscape.cpp)?
490 Inkscape::NSApplication::Application app(argc, argv, use_gui, sp_new_gui);
492 return app.run();
493 }
495 void fixupSingleFilename( gchar **orig, gchar **spare )
496 {
497 if ( orig && *orig && **orig ) {
498 GError *error = NULL;
499 gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(*orig, -1, NULL, NULL, &error);
500 if ( newFileName )
501 {
502 *orig = newFileName;
503 if ( spare ) {
504 *spare = newFileName;
505 }
506 // g_message("Set a replacement fixup");
507 }
508 }
509 }
511 GSList *fixupFilenameEncoding( GSList* fl )
512 {
513 GSList *newFl = NULL;
514 while ( fl ) {
515 gchar *fn = static_cast<gchar*>(fl->data);
516 fl = g_slist_remove( fl, fl->data );
517 gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(fn, -1, NULL, NULL, NULL);
518 if ( newFileName ) {
520 if ( 0 )
521 {
522 gchar *safeFn = Inkscape::IO::sanitizeString(fn);
523 gchar *safeNewFn = Inkscape::IO::sanitizeString(newFileName);
524 GtkWidget *w = gtk_message_dialog_new( NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
525 "Note: Converted '%s' to '%s'", safeFn, safeNewFn );
526 gtk_dialog_run (GTK_DIALOG (w));
527 gtk_widget_destroy (w);
528 g_free(safeNewFn);
529 g_free(safeFn);
530 }
532 g_free( fn );
533 fn = newFileName;
534 newFileName = 0;
535 }
536 else
537 if ( 0 )
538 {
539 gchar *safeFn = Inkscape::IO::sanitizeString(fn);
540 GtkWidget *w = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "Error: Unable to convert '%s'", safeFn );
541 gtk_dialog_run (GTK_DIALOG (w));
542 gtk_widget_destroy (w);
543 g_free(safeFn);
544 }
545 newFl = g_slist_append( newFl, fn );
546 }
547 return newFl;
548 }
550 int sp_common_main( int argc, char const **argv, GSList **flDest )
551 {
552 /// \todo fixme: Move these to some centralized location (Lauris)
553 sp_object_type_register("sodipodi:namedview", SP_TYPE_NAMEDVIEW);
554 sp_object_type_register("sodipodi:guide", SP_TYPE_GUIDE);
557 // temporarily switch gettext encoding to locale, so that help messages can be output properly
558 gchar const *charset;
559 g_get_charset(&charset);
561 bind_textdomain_codeset(GETTEXT_PACKAGE, charset);
563 poptContext ctx = poptGetContext(NULL, argc, argv, options, 0);
564 poptSetOtherOptionHelp(ctx, _("[OPTIONS...] [FILE...]\n\nAvailable options:"));
565 g_return_val_if_fail(ctx != NULL, 1);
567 /* Collect own arguments */
568 GSList *fl = sp_process_args(ctx);
569 poptFreeContext(ctx);
571 // now switch gettext back to UTF-8 (for GUI)
572 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
574 // Now let's see if the file list still holds up
575 if ( needToRecodeParams )
576 {
577 fl = fixupFilenameEncoding( fl );
578 }
580 // Check the globals for filename-fixup
581 if ( needToRecodeParams )
582 {
583 fixupSingleFilename( &sp_export_png, &sp_export_png_utf8 );
584 fixupSingleFilename( &sp_export_svg, &sp_export_svg_utf8 );
585 fixupSingleFilename( &sp_global_printer, &sp_global_printer_utf8 );
586 }
587 else
588 {
589 if ( sp_export_png )
590 sp_export_png_utf8 = g_strdup( sp_export_png );
591 if ( sp_export_svg )
592 sp_export_svg_utf8 = g_strdup( sp_export_svg );
593 if ( sp_global_printer )
594 sp_global_printer_utf8 = g_strdup( sp_global_printer );
595 }
597 // Return the list if wanted, else free it up.
598 if ( flDest ) {
599 *flDest = fl;
600 fl = 0;
601 } else {
602 while ( fl ) {
603 g_free( fl->data );
604 fl = g_slist_remove( fl, fl->data );
605 }
606 }
607 return 0;
608 }
610 int
611 sp_main_gui(int argc, char const **argv)
612 {
613 Gtk::Main main_instance (&argc, const_cast<char ***>(&argv));
615 GSList *fl = NULL;
616 int retVal = sp_common_main( argc, argv, &fl );
617 g_return_val_if_fail(retVal == 0, 1);
619 inkscape_gtk_stock_init();
621 /* Set default icon */
622 gchar *filename = (gchar *) g_build_filename (INKSCAPE_APPICONDIR, "inkscape.png", NULL);
623 if (Inkscape::IO::file_test(filename, (GFileTest)(G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK))) {
624 gtk_window_set_default_icon_from_file(filename, NULL);
625 }
626 g_free (filename);
627 filename = 0;
629 if (!sp_global_slideshow) {
630 gboolean create_new = TRUE;
632 /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
633 inkscape_application_init(argv[0], true);
635 while (fl) {
636 if (sp_file_open((gchar *)fl->data,NULL)) {
637 create_new=FALSE;
638 }
639 fl = g_slist_remove(fl, fl->data);
640 }
641 if (create_new) {
642 sp_file_new_default();
643 }
644 } else {
645 if (fl) {
646 GtkWidget *ss;
647 /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
648 inkscape_application_init(argv[0], true);
649 ss = sp_slideshow_new(fl);
650 if (ss) gtk_widget_show(ss);
651 } else {
652 g_warning ("No slides to display");
653 exit(0);
654 }
655 }
657 main_instance.run();
659 #ifdef WIN32
660 //We might not need anything here
661 //sp_win32_finish(); <-- this is a NOP func
662 #endif
664 return 0;
665 }
667 int
668 sp_main_console(int argc, char const **argv)
669 {
670 /* We are started in text mode */
672 /* Do this g_type_init(), so that we can use Xft/Freetype2 (Pango)
673 * in a non-Gtk environment. Used in libnrtype's
674 * FontInstance.cpp and FontFactory.cpp.
675 * http://mail.gnome.org/archives/gtk-list/2003-December/msg00063.html
676 */
677 g_type_init();
678 char **argv2 = const_cast<char **>(argv);
679 gtk_init_check( &argc, &argv2 );
680 //setlocale(LC_ALL, "");
682 GSList *fl = NULL;
683 int retVal = sp_common_main( argc, argv, &fl );
684 g_return_val_if_fail(retVal == 0, 1);
686 if (fl == NULL) {
687 g_print("Nothing to do!\n");
688 exit(0);
689 }
691 inkscape_application_init(argv[0], false);
693 while (fl) {
694 SPDocument *doc;
696 doc = Inkscape::Extension::open(NULL, (gchar *)fl->data);
697 if (doc == NULL) {
698 doc = Inkscape::Extension::open(Inkscape::Extension::db.get(SP_MODULE_KEY_INPUT_SVG), (gchar *)fl->data);
699 }
700 if (doc == NULL) {
701 g_warning("Specified document %s cannot be opened (is it valid SVG file?)", (gchar *) fl->data);
702 } else {
703 if (sp_vacuum_defs) {
704 vacuum_document(doc);
705 }
706 if (sp_vacuum_defs && !sp_export_svg) {
707 // save under the name given in the command line
708 sp_repr_save_file(doc->rdoc, (gchar *)fl->data, SP_SVG_NS_URI);
709 }
710 if (sp_global_printer) {
711 sp_print_document_to_file(doc, sp_global_printer);
712 }
713 if (sp_export_png || sp_export_id || sp_export_area_drawing) {
714 sp_do_export_png(doc);
715 }
716 if (sp_export_svg) {
717 Inkscape::XML::Document *rdoc;
718 Inkscape::XML::Node *repr;
719 rdoc = sp_repr_document_new("svg:svg");
720 repr = rdoc->root();
721 repr = sp_document_root(doc)->updateRepr(repr, SP_OBJECT_WRITE_BUILD);
722 sp_repr_save_file(repr->document(), sp_export_svg, SP_SVG_NS_URI);
723 }
724 if (sp_export_ps) {
725 do_export_ps(doc, sp_export_ps, "image/x-postscript");
726 }
727 if (sp_export_eps) {
728 do_export_ps(doc, sp_export_eps, "image/x-e-postscript");
729 }
730 if (sp_export_pdf) {
731 do_export_pdf(doc, sp_export_pdf, "application/pdf");
732 }
733 if (sp_query_width || sp_query_height) {
734 do_query_dimension (doc, true, sp_query_width? NR::X : NR::Y, sp_query_id);
735 } else if (sp_query_x || sp_query_y) {
736 do_query_dimension (doc, false, sp_query_x? NR::X : NR::Y, sp_query_id);
737 }
738 }
739 fl = g_slist_remove(fl, fl->data);
740 }
742 inkscape_unref();
744 return 0;
745 }
747 static void
748 do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gchar *id)
749 {
750 SPObject *o = NULL;
752 if (id) {
753 o = doc->getObjectById(id);
754 if (o) {
755 if (!SP_IS_ITEM (o)) {
756 g_warning("Object with id=\"%s\" is not a visible item. Cannot query dimensions.", id);
757 return;
758 }
759 } else {
760 g_warning("Object with id=\"%s\" is not found. Cannot query dimensions.", id);
761 return;
762 }
763 } else {
764 o = SP_DOCUMENT_ROOT(doc);
765 }
767 if (o) {
768 sp_document_ensure_up_to_date (doc);
769 SPItem *item = ((SPItem *) o);
770 NR::Rect area = item->invokeBbox(sp_item_i2doc_affine(item)); // "true" SVG bbox for scripting
772 Inkscape::SVGOStringStream os;
773 if (extent) {
774 os << area.extent(axis);
775 } else {
776 os << area.min()[axis];
777 }
778 g_print ("%s", os.str().c_str());
779 }
780 }
783 static void
784 sp_do_export_png(SPDocument *doc)
785 {
786 const gchar *filename = NULL;
787 gdouble dpi = 0.0;
789 if (sp_export_use_hints && (!sp_export_id && !sp_export_area_drawing)) {
790 g_warning ("--export-use-hints can only be used with --export-id or --export-area-drawing; ignored.");
791 }
793 GSList *items = NULL;
795 NRRect area;
796 if (sp_export_id || sp_export_area_drawing) {
798 SPObject *o = NULL;
799 SPObject *o_area = NULL;
800 if (sp_export_id && sp_export_area_drawing) {
801 o = doc->getObjectById(sp_export_id);
802 o_area = SP_DOCUMENT_ROOT (doc);
803 } else if (sp_export_id) {
804 o = doc->getObjectById(sp_export_id);
805 o_area = o;
806 } else if (sp_export_area_drawing) {
807 o = SP_DOCUMENT_ROOT (doc);
808 o_area = o;
809 }
811 if (o) {
812 if (!SP_IS_ITEM (o)) {
813 g_warning("Object with id=\"%s\" is not a visible item. Nothing exported.", sp_export_id);
814 return;
815 }
817 items = g_slist_prepend (items, SP_ITEM(o));
819 if (sp_export_id_only) {
820 g_print("Exporting only object with id=\"%s\"; all other objects hidden\n", sp_export_id);
821 }
823 if (sp_export_use_hints) {
825 // retrieve export filename hint
826 const gchar *fn_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-filename");
827 if (fn_hint) {
828 if (sp_export_png) {
829 g_warning ("Using export filename from the command line (--export-png). Filename hint %s is ignored.", fn_hint);
830 filename = sp_export_png;
831 } else {
832 filename = fn_hint;
833 }
834 } else {
835 g_warning ("Export filename hint not found for the object.");
836 filename = sp_export_png;
837 }
839 // retrieve export dpi hints
840 const gchar *dpi_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-xdpi"); // only xdpi, ydpi is always the same now
841 if (dpi_hint) {
842 if (sp_export_dpi || sp_export_width || sp_export_height) {
843 g_warning ("Using bitmap dimensions from the command line (--export-dpi, --export-width, or --export-height). DPI hint %s is ignored.", dpi_hint);
844 } else {
845 dpi = atof(dpi_hint);
846 }
847 } else {
848 g_warning ("Export DPI hint not found for the object.");
849 }
851 }
853 // write object bbox to area
854 sp_document_ensure_up_to_date (doc);
855 sp_item_invoke_bbox((SPItem *) o_area, &area, sp_item_i2r_affine((SPItem *) o_area), TRUE);
856 } else {
857 g_warning("Object with id=\"%s\" was not found in the document. Nothing exported.", sp_export_id);
858 return;
859 }
860 }
862 if (sp_export_area) {
863 /* Try to parse area (given in SVG pixels) */
864 if (!sscanf(sp_export_area, "%lg:%lg:%lg:%lg", &area.x0, &area.y0, &area.x1, &area.y1) == 4) {
865 g_warning("Cannot parse export area '%s'; use 'x0:y0:x1:y1'. Nothing exported.", sp_export_area);
866 return;
867 }
868 if ((area.x0 >= area.x1) || (area.y0 >= area.y1)) {
869 g_warning("Export area '%s' has negative width or height. Nothing exported.", sp_export_area);
870 return;
871 }
872 } else if (sp_export_area_canvas || !(sp_export_id || sp_export_area_drawing)) {
873 /* Export the whole canvas */
874 sp_document_ensure_up_to_date (doc);
875 area.x0 = SP_ROOT(doc->root)->x.computed;
876 area.y0 = SP_ROOT(doc->root)->y.computed;
877 area.x1 = area.x0 + sp_document_width (doc);
878 area.y1 = area.y0 + sp_document_height (doc);
879 }
881 // set filename and dpi from options, if not yet set from the hints
882 if (!filename) {
883 if (!sp_export_png) {
884 g_warning ("No export filename given and no filename hint. Nothing exported.");
885 return;
886 }
887 filename = sp_export_png;
888 }
890 if (sp_export_dpi && dpi == 0.0) {
891 dpi = atof(sp_export_dpi);
892 if ((dpi < 0.1) || (dpi > 10000.0)) {
893 g_warning("DPI value %s out of range [0.1 - 10000.0]. Nothing exported.", sp_export_dpi);
894 return;
895 }
896 g_print("DPI: %g\n", dpi);
897 }
899 if (sp_export_area_snap) {
900 area.x0 = std::floor (area.x0);
901 area.y0 = std::floor (area.y0);
902 area.x1 = std::ceil (area.x1);
903 area.y1 = std::ceil (area.y1);
904 }
906 // default dpi
907 if (dpi == 0.0)
908 dpi = PX_PER_IN;
910 gint width = 0;
911 gint height = 0;
913 if (sp_export_width) {
914 width = atoi(sp_export_width);
915 if ((width < 1) || (width > 65536)) {
916 g_warning("Export width %d out of range (1 - 65536). Nothing exported.", width);
917 return;
918 }
919 dpi = (gdouble) width * PX_PER_IN / (area.x1 - area.x0);
920 }
922 if (sp_export_height) {
923 height = atoi(sp_export_height);
924 if ((height < 1) || (height > 65536)) {
925 g_warning("Export height %d out of range (1 - 65536). Nothing exported.", width);
926 return;
927 }
928 dpi = (gdouble) height * PX_PER_IN / (area.y1 - area.y0);
929 }
931 if (!sp_export_width) {
932 width = (gint) ((area.x1 - area.x0) * dpi / PX_PER_IN + 0.5);
933 }
935 if (!sp_export_height) {
936 height = (gint) ((area.y1 - area.y0) * dpi / PX_PER_IN + 0.5);
937 }
939 guint32 bgcolor = 0x00000000;
940 if (sp_export_background) {
941 // override the page color
942 bgcolor = sp_svg_read_color(sp_export_background, 0xffffff00);
943 bgcolor |= 0xff; // default is no opacity
944 } else {
945 // read from namedview
946 Inkscape::XML::Node *nv = sp_repr_lookup_name (doc->rroot, "sodipodi:namedview");
947 if (nv && nv->attribute("pagecolor"))
948 bgcolor = sp_svg_read_color(nv->attribute("pagecolor"), 0xffffff00);
949 if (nv && nv->attribute("inkscape:pageopacity"))
950 bgcolor |= SP_COLOR_F_TO_U(sp_repr_get_double_attribute (nv, "inkscape:pageopacity", 1.0));
951 }
953 if (sp_export_background_opacity) {
954 // override opacity
955 gfloat value;
956 if (sp_svg_number_read_f (sp_export_background_opacity, &value)) {
957 if (value > 1.0) {
958 value = CLAMP (value, 1.0f, 255.0f);
959 bgcolor &= (guint32) 0xffffff00;
960 bgcolor |= (guint32) floor(value);
961 } else {
962 value = CLAMP (value, 0.0f, 1.0f);
963 bgcolor &= (guint32) 0xffffff00;
964 bgcolor |= SP_COLOR_F_TO_U(value);
965 }
966 }
967 }
969 g_print("Background RRGGBBAA: %08x\n", bgcolor);
971 g_print("Area %g:%g:%g:%g exported to %d x %d pixels (%g dpi)\n", area.x0, area.y0, area.x1, area.y1, width, height, dpi);
973 g_print("Bitmap saved as: %s\n", filename);
975 if ((width >= 1) && (height >= 1) && (width < 65536) && (height < 65536)) {
976 sp_export_png_file(doc, filename, area.x0, area.y0, area.x1, area.y1, width, height, dpi, dpi, bgcolor, NULL, NULL, true, sp_export_id_only ? items : NULL);
977 } else {
978 g_warning("Calculated bitmap dimensions %d %d are out of range (1 - 65535). Nothing exported.", width, height);
979 }
981 g_slist_free (items);
982 }
985 /**
986 * Perform an export of either PS or EPS.
987 *
988 * \param doc Document to export.
989 * \param uri URI to export to.
990 * \param mime MIME type to export as.
991 */
993 static void do_export_ps(SPDocument* doc, gchar const* uri, char const* mime)
994 {
995 Inkscape::Extension::DB::OutputList o;
996 Inkscape::Extension::db.get_output_list(o);
997 Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
998 while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
999 i++;
1000 }
1002 if (i == o.end())
1003 {
1004 g_warning ("Could not find an extension to export this file.");
1005 return;
1006 }
1008 bool old_text_to_path = false;
1009 bool old_font_embedded = false;
1010 bool old_bbox_page = false;
1012 try {
1013 old_text_to_path = (*i)->get_param_bool("textToPath");
1014 (*i)->set_param_bool("textToPath", sp_export_text_to_path);
1015 }
1016 catch (...) {
1017 g_warning ("Could not set export-text-to-path option for this export.");
1018 }
1020 try {
1021 old_font_embedded = (*i)->get_param_bool("fontEmbedded");
1022 (*i)->set_param_bool("fontEmbedded", sp_export_font);
1023 }
1024 catch (...) {
1025 g_warning ("Could not set export-font option for this export.");
1026 }
1028 try {
1029 old_bbox_page = (*i)->get_param_bool("pageBoundingBox");
1030 (*i)->set_param_bool("pageBoundingBox", sp_export_bbox_page);
1031 }
1032 catch (...) {
1033 g_warning ("Could not set export-bbox-page option for this export.");
1034 }
1036 (*i)->save(doc, uri);
1038 try {
1039 (*i)->set_param_bool("textToPath", old_text_to_path);
1040 (*i)->set_param_bool("fontEmbedded", old_font_embedded);
1041 (*i)->set_param_bool("pageBoundingBox", old_bbox_page);
1042 }
1043 catch (...) {
1045 }
1046 }
1048 /**
1049 * Perform a PDF export
1050 *
1051 * \param doc Document to export.
1052 * \param uri URI to export to.
1053 * \param mime MIME type to export as.
1054 */
1056 static void do_export_pdf(SPDocument* doc, gchar const* uri, char const* mime)
1057 {
1058 Inkscape::Extension::DB::OutputList o;
1059 Inkscape::Extension::db.get_output_list(o);
1060 Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
1061 while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
1062 i++;
1063 }
1065 if (i == o.end())
1066 {
1067 g_warning ("Could not find an extension to export this file.");
1068 return;
1069 }
1071 (*i)->save(doc, uri);
1072 }
1074 #ifdef WIN32
1075 bool replaceArgs( int& argc, char**& argv )
1076 {
1077 bool worked = false;
1079 #ifdef REPLACEARGS_DEBUG
1080 MessageBoxA( NULL, "GetCommandLineW() getting called", "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1081 #endif // REPLACEARGS_DEBUG
1083 wchar_t* line = GetCommandLineW();
1084 if ( line )
1085 {
1086 #ifdef REPLACEARGS_DEBUG
1087 {
1088 gchar* utf8Line = g_utf16_to_utf8( (gunichar2*)line, -1, NULL, NULL, NULL );
1089 if ( utf8Line )
1090 {
1091 gchar *safe = Inkscape::IO::sanitizeString(utf8Line);
1092 {
1093 char tmp[strlen(safe) + 32];
1094 snprintf( tmp, sizeof(tmp), "GetCommandLineW() = '%s'", safe );
1095 MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1096 }
1097 }
1098 }
1099 #endif // REPLACEARGS_DEBUG
1101 int numArgs = 0;
1102 wchar_t** parsed = CommandLineToArgvW( line, &numArgs );
1104 #ifdef REPLACEARGS_ANSI
1105 // test code for trying things on Win95/98/ME
1106 if ( !parsed )
1107 {
1108 #ifdef REPLACEARGS_DEBUG
1109 MessageBoxA( NULL, "Unable to process command-line. Faking it", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1110 #endif // REPLACEARGS_DEBUG
1111 int lineLen = wcslen(line) + 1;
1112 wchar_t* lineDup = new wchar_t[lineLen];
1113 wcsncpy( lineDup, line, lineLen );
1115 int pos = 0;
1116 bool inQuotes = false;
1117 bool inWhitespace = true;
1118 std::vector<int> places;
1119 while ( lineDup[pos] )
1120 {
1121 if ( inQuotes )
1122 {
1123 if ( lineDup[pos] == L'"' )
1124 {
1125 inQuotes = false;
1126 }
1127 }
1128 else if ( lineDup[pos] == L'"' )
1129 {
1130 inQuotes = true;
1131 inWhitespace = false;
1132 places.push_back(pos);
1133 }
1134 else if ( lineDup[pos] == L' ' || lineDup[pos] == L'\t' )
1135 {
1136 if ( !inWhitespace )
1137 {
1138 inWhitespace = true;
1139 lineDup[pos] = 0;
1140 }
1141 }
1142 else if ( inWhitespace && (lineDup[pos] != L' ' && lineDup[pos] != L'\t') )
1143 {
1144 inWhitespace = false;
1145 places.push_back(pos);
1146 }
1147 else
1148 {
1149 // consume
1150 }
1151 pos++;
1152 }
1153 #ifdef REPLACEARGS_DEBUG
1154 {
1155 char tmp[256];
1156 snprintf( tmp, sizeof(tmp), "Counted %d args", places.size() );
1157 MessageBoxA( NULL, tmp, "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1158 }
1159 #endif // REPLACEARGS_DEBUG
1161 wchar_t** block = new wchar_t*[places.size()];
1162 int i = 0;
1163 for ( std::vector<int>::iterator it = places.begin(); it != places.end(); it++ )
1164 {
1165 block[i++] = &lineDup[*it];
1166 }
1167 parsed = block;
1168 numArgs = places.size();
1169 }
1170 #endif // REPLACEARGS_ANSI
1172 if ( parsed )
1173 {
1174 std::vector<wchar_t*>expandedArgs;
1175 if ( numArgs > 0 )
1176 {
1177 expandedArgs.push_back( parsed[0] );
1178 }
1180 for ( int i1 = 1; i1 < numArgs; i1++ )
1181 {
1182 bool wildcarded = (wcschr(parsed[i1], L'?') != NULL) || (wcschr(parsed[i1], L'*') != NULL);
1183 wildcarded &= parsed[i1][0] != L'"';
1184 wildcarded &= parsed[i1][0] != L'-';
1185 if ( wildcarded )
1186 {
1187 #ifdef REPLACEARGS_ANSI
1188 WIN32_FIND_DATAA data = {0};
1189 #else
1190 WIN32_FIND_DATAW data = {0};
1191 #endif // REPLACEARGS_ANSI
1193 int baseLen = wcslen(parsed[i1]) + 2;
1194 wchar_t* base = new wchar_t[baseLen];
1195 wcsncpy( base, parsed[i1], baseLen );
1196 wchar_t* last = wcsrchr( base, L'\\' );
1197 if ( last )
1198 {
1199 last[1] = 0;
1200 }
1201 else
1202 {
1203 base[0] = 0;
1204 }
1205 baseLen = wcslen( base );
1207 #ifdef REPLACEARGS_ANSI
1208 char target[MAX_PATH];
1209 if ( WideCharToMultiByte( CP_ACP, 0, parsed[i1], -1, target, sizeof(target), NULL, NULL) )
1210 {
1211 HANDLE hf = FindFirstFileA( target, &data );
1212 #else
1213 HANDLE hf = FindFirstFileW( parsed[i1], &data );
1214 #endif // REPLACEARGS_ANSI
1215 if ( hf != INVALID_HANDLE_VALUE )
1216 {
1217 BOOL found = TRUE;
1218 do
1219 {
1220 #ifdef REPLACEARGS_ANSI
1221 int howMany = MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, NULL, 0 );
1222 if ( howMany > 0 )
1223 {
1224 howMany += baseLen;
1225 wchar_t* tmp = new wchar_t[howMany + 1];
1226 wcsncpy( tmp, base, howMany + 1 );
1227 MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, tmp + baseLen, howMany + 1 - baseLen );
1228 expandedArgs.push_back( tmp );
1229 found = FindNextFileA( hf, &data );
1230 }
1231 #else
1232 int howMany = wcslen(data.cFileName) + baseLen;
1233 wchar_t* tmp = new wchar_t[howMany + 1];
1234 wcsncpy( tmp, base, howMany + 1 );
1235 wcsncat( tmp, data.cFileName, howMany + 1 );
1236 expandedArgs.push_back( tmp );
1237 found = FindNextFileW( hf, &data );
1238 #endif // REPLACEARGS_ANSI
1239 } while ( found );
1241 FindClose( hf );
1242 }
1243 else
1244 {
1245 expandedArgs.push_back( parsed[i1] );
1246 }
1247 #ifdef REPLACEARGS_ANSI
1248 }
1249 #endif // REPLACEARGS_ANSI
1251 delete[] base;
1252 }
1253 else
1254 {
1255 expandedArgs.push_back( parsed[i1] );
1256 }
1257 }
1259 {
1260 wchar_t** block = new wchar_t*[expandedArgs.size()];
1261 int iz = 0;
1262 for ( std::vector<wchar_t*>::iterator it = expandedArgs.begin(); it != expandedArgs.end(); it++ )
1263 {
1264 block[iz++] = *it;
1265 }
1266 parsed = block;
1267 numArgs = expandedArgs.size();
1268 }
1270 std::vector<gchar*> newArgs;
1271 for ( int i = 0; i < numArgs; i++ )
1272 {
1273 gchar* replacement = g_utf16_to_utf8( (gunichar2*)parsed[i], -1, NULL, NULL, NULL );
1274 if ( replacement )
1275 {
1276 #ifdef REPLACEARGS_DEBUG
1277 gchar *safe2 = Inkscape::IO::sanitizeString(replacement);
1279 if ( safe2 )
1280 {
1281 {
1282 char tmp[1024];
1283 snprintf( tmp, sizeof(tmp), " [%2d] = '%s'", i, safe2 );
1284 MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1285 }
1286 g_free( safe2 );
1287 }
1288 #endif // REPLACEARGS_DEBUG
1290 newArgs.push_back( replacement );
1291 }
1292 else
1293 {
1294 newArgs.push_back( blankParam );
1295 }
1296 }
1298 // Now push our munged params to be the new argv and argc
1299 {
1300 char** block = new char*[newArgs.size()];
1301 int iz = 0;
1302 for ( std::vector<char*>::iterator it = newArgs.begin(); it != newArgs.end(); it++ )
1303 {
1304 block[iz++] = *it;
1305 }
1306 argv = block;
1307 argc = newArgs.size();
1308 worked = true;
1309 }
1310 }
1311 #ifdef REPLACEARGS_DEBUG
1312 else
1313 {
1314 MessageBoxA( NULL, "Unable to process command-line", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1315 }
1316 #endif // REPLACEARGS_DEBUG
1317 }
1318 #ifdef REPLACEARGS_DEBUG
1319 else
1320 {
1321 {
1322 MessageBoxA( NULL, "Unable to fetch result from GetCommandLineW()", "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1323 }
1325 char* line2 = GetCommandLineA();
1326 if ( line2 )
1327 {
1328 gchar *safe = Inkscape::IO::sanitizeString(line2);
1329 {
1330 {
1331 char tmp[strlen(safe) + 32];
1332 snprintf( tmp, sizeof(tmp), "GetCommandLineA() = '%s'", safe );
1333 MessageBoxA( NULL, tmp, "GetCommandLineA", MB_OK | MB_ICONINFORMATION );
1334 }
1335 }
1336 }
1337 else
1338 {
1339 MessageBoxA( NULL, "Unable to fetch result from GetCommandLineA()", "GetCommandLineA", MB_OK | MB_ICONINFORMATION );
1340 }
1341 }
1342 #endif // REPLACEARGS_DEBUG
1344 return worked;
1345 }
1346 #endif // WIN32
1348 static GSList *
1349 sp_process_args(poptContext ctx)
1350 {
1351 GSList *fl = NULL;
1353 gint a;
1354 while ((a = poptGetNextOpt(ctx)) >= 0) {
1355 switch (a) {
1356 case SP_ARG_FILE: {
1357 gchar const *fn = poptGetOptArg(ctx);
1358 if (fn != NULL) {
1359 fl = g_slist_append(fl, g_strdup(fn));
1360 }
1361 break;
1362 }
1363 case SP_ARG_VERSION: {
1364 printf("Inkscape %s (%s)\n", INKSCAPE_VERSION, __DATE__);
1365 exit(0);
1366 break;
1367 }
1368 case SP_ARG_EXTENSIONDIR: {
1369 printf("%s\n", INKSCAPE_EXTENSIONDIR);
1370 exit(0);
1371 break;
1372 }
1373 default: {
1374 break;
1375 }
1376 }
1377 }
1379 gchar const ** const args = poptGetArgs(ctx);
1380 if (args != NULL) {
1381 for (unsigned i = 0; args[i] != NULL; i++) {
1382 fl = g_slist_append(fl, g_strdup(args[i]));
1383 }
1384 }
1386 return fl;
1387 }
1390 /*
1391 Local Variables:
1392 mode:c++
1393 c-file-style:"stroustrup"
1394 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
1395 indent-tabs-mode:nil
1396 fill-column:99
1397 End:
1398 */
1399 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :