877f4df9f1f1814513a1fb2c18ce36b6a26e2bfd
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 {"fit-page-to-drawing", 'S',
325 POPT_ARG_NONE, &sp_export_bbox_page, SP_ARG_FIT_PAGE_TO_DRAWING,
326 N_("Fits page to drawing and saves changes in place"),
327 NULL},
329 {"query-x", 'X',
330 POPT_ARG_NONE, &sp_query_x, SP_ARG_QUERY_X,
331 // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
332 N_("Query the X coordinate of the drawing or, if specified, of the object with --query-id"),
333 NULL},
335 {"query-y", 'Y',
336 POPT_ARG_NONE, &sp_query_y, SP_ARG_QUERY_Y,
337 // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
338 N_("Query the Y coordinate of the drawing or, if specified, of the object with --query-id"),
339 NULL},
341 {"query-width", 'W',
342 POPT_ARG_NONE, &sp_query_width, SP_ARG_QUERY_WIDTH,
343 // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
344 N_("Query the width of the drawing or, if specified, of the object with --query-id"),
345 NULL},
347 {"query-height", 'H',
348 POPT_ARG_NONE, &sp_query_height, SP_ARG_QUERY_HEIGHT,
349 // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
350 N_("Query the height of the drawing or, if specified, of the object with --query-id"),
351 NULL},
353 {"query-id", 'I',
354 POPT_ARG_STRING, &sp_query_id, SP_ARG_QUERY_ID,
355 N_("The ID of the object whose dimensions are queried"),
356 N_("ID")},
358 {"extension-directory", 'x',
359 POPT_ARG_NONE, NULL, SP_ARG_EXTENSIONDIR,
360 // TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory
361 N_("Print out the extension directory and exit"),
362 NULL},
364 {"slideshow", 's',
365 POPT_ARG_NONE, &sp_global_slideshow, SP_ARG_SLIDESHOW,
366 N_("Show given files one-by-one, switch to next on any key/mouse event"),
367 NULL},
369 {"vacuum-defs", 0,
370 POPT_ARG_NONE, &sp_vacuum_defs, SP_ARG_VACUUM_DEFS,
371 N_("Remove unused definitions from the defs section(s) of the document"),
372 NULL},
374 POPT_AUTOHELP POPT_TABLEEND
375 };
377 static bool needToRecodeParams = true;
378 gchar* blankParam = "";
380 int
381 main(int argc, char **argv)
382 {
383 #ifdef HAVE_FPSETMASK
384 /* This is inherited from Sodipodi code, where it was in #ifdef __FreeBSD__. It's probably
385 safe to remove: the default mask is already 0 in C99, and in current FreeBSD according to
386 the fenv man page on www.freebsd.org, and in glibc according to (libc)FP Exceptions. */
387 fpsetmask(fpgetmask() & ~(FP_X_DZ | FP_X_INV));
388 #endif
390 #ifdef ENABLE_NLS
391 #ifdef WIN32
392 RegistryTool rt;
393 rt.setPathInfo();
394 gchar *pathBuf = g_strconcat(g_path_get_dirname(argv[0]), "\\", PACKAGE_LOCALE_DIR, NULL);
395 bindtextdomain(GETTEXT_PACKAGE, pathBuf);
396 g_free(pathBuf);
397 #else
398 #ifdef ENABLE_BINRELOC
399 bindtextdomain(GETTEXT_PACKAGE, BR_LOCALEDIR(""));
400 #else
401 bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
402 #endif
403 #endif
404 #endif
406 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
408 #ifdef ENABLE_NLS
409 textdomain(GETTEXT_PACKAGE);
410 #endif
412 LIBXML_TEST_VERSION
414 Inkscape::GC::init();
416 Inkscape::Debug::Logger::init();
418 gboolean use_gui;
419 #ifndef WIN32
420 use_gui = (getenv("DISPLAY") != NULL);
421 #else
422 /*
423 Set the current directory to the directory of the
424 executable. This seems redundant, but is needed for
425 when inkscape.exe is executed from another directory.
426 We use relative paths on win32.
427 HKCR\svgfile\shell\open\command is a good example
428 */
429 /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
430 char *homedir = g_path_get_dirname(argv[0]);
431 SetCurrentDirectory(homedir);
432 g_free(homedir);
434 use_gui = TRUE;
435 #endif
436 /* Test whether with/without GUI is forced */
437 for (int i = 1; i < argc; i++) {
438 if (!strcmp(argv[i], "-z")
439 || !strcmp(argv[i], "--without-gui")
440 || !strcmp(argv[i], "-p")
441 || !strncmp(argv[i], "--print", 7)
442 || !strcmp(argv[i], "-e")
443 || !strncmp(argv[i], "--export-png", 12)
444 || !strcmp(argv[i], "-l")
445 || !strncmp(argv[i], "--export-plain-svg", 12)
446 || !strcmp(argv[i], "-i")
447 || !strncmp(argv[i], "--export-area-drawing", 21)
448 || !strcmp(argv[i], "-D")
449 || !strncmp(argv[i], "--export-area-canvas", 20)
450 || !strcmp(argv[i], "-C")
451 || !strncmp(argv[i], "--export-id", 12)
452 || !strcmp(argv[i], "-P")
453 || !strncmp(argv[i], "--export-ps", 11)
454 || !strcmp(argv[i], "-E")
455 || !strncmp(argv[i], "--export-eps", 12)
456 || !strcmp(argv[i], "-A")
457 || !strncmp(argv[i], "--export-pdf", 12)
458 || !strcmp(argv[i], "-W")
459 || !strncmp(argv[i], "--query-width", 13)
460 || !strcmp(argv[i], "-H")
461 || !strncmp(argv[i], "--query-height", 14)
462 || !strcmp(argv[i], "-X")
463 || !strncmp(argv[i], "--query-x", 13)
464 || !strcmp(argv[i], "-Y")
465 || !strncmp(argv[i], "--query-y", 14)
466 || !strcmp(argv[i], "--vacuum-defs")
467 )
468 {
469 /* main_console handles any exports -- not the gui */
470 use_gui = FALSE;
471 break;
472 } else if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--with-gui")) {
473 use_gui = TRUE;
474 break;
475 }
476 }
478 #ifdef WIN32
479 #ifndef REPLACEARGS_ANSI
480 if ( PrintWin32::is_os_wide() )
481 #endif // REPLACEARGS_ANSI
482 {
483 // If the call fails, we'll need to convert charsets
484 needToRecodeParams = !replaceArgs( argc, argv );
485 }
486 #endif // WIN32
488 /// \todo Should this be a static object (see inkscape.cpp)?
489 Inkscape::NSApplication::Application app(argc, argv, use_gui, sp_new_gui);
491 return app.run();
492 }
494 void fixupSingleFilename( gchar **orig, gchar **spare )
495 {
496 if ( orig && *orig && **orig ) {
497 GError *error = NULL;
498 gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(*orig, -1, NULL, NULL, &error);
499 if ( newFileName )
500 {
501 *orig = newFileName;
502 if ( spare ) {
503 *spare = newFileName;
504 }
505 // g_message("Set a replacement fixup");
506 }
507 }
508 }
510 GSList *fixupFilenameEncoding( GSList* fl )
511 {
512 GSList *newFl = NULL;
513 while ( fl ) {
514 gchar *fn = static_cast<gchar*>(fl->data);
515 fl = g_slist_remove( fl, fl->data );
516 gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(fn, -1, NULL, NULL, NULL);
517 if ( newFileName ) {
519 if ( 0 )
520 {
521 gchar *safeFn = Inkscape::IO::sanitizeString(fn);
522 gchar *safeNewFn = Inkscape::IO::sanitizeString(newFileName);
523 GtkWidget *w = gtk_message_dialog_new( NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
524 "Note: Converted '%s' to '%s'", safeFn, safeNewFn );
525 gtk_dialog_run (GTK_DIALOG (w));
526 gtk_widget_destroy (w);
527 g_free(safeNewFn);
528 g_free(safeFn);
529 }
531 g_free( fn );
532 fn = newFileName;
533 newFileName = 0;
534 }
535 else
536 if ( 0 )
537 {
538 gchar *safeFn = Inkscape::IO::sanitizeString(fn);
539 GtkWidget *w = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "Error: Unable to convert '%s'", safeFn );
540 gtk_dialog_run (GTK_DIALOG (w));
541 gtk_widget_destroy (w);
542 g_free(safeFn);
543 }
544 newFl = g_slist_append( newFl, fn );
545 }
546 return newFl;
547 }
549 int sp_common_main( int argc, char const **argv, GSList **flDest )
550 {
551 /// \todo fixme: Move these to some centralized location (Lauris)
552 sp_object_type_register("sodipodi:namedview", SP_TYPE_NAMEDVIEW);
553 sp_object_type_register("sodipodi:guide", SP_TYPE_GUIDE);
556 // temporarily switch gettext encoding to locale, so that help messages can be output properly
557 gchar const *charset;
558 g_get_charset(&charset);
560 bind_textdomain_codeset(GETTEXT_PACKAGE, charset);
562 poptContext ctx = poptGetContext(NULL, argc, argv, options, 0);
563 poptSetOtherOptionHelp(ctx, _("[OPTIONS...] [FILE...]\n\nAvailable options:"));
564 g_return_val_if_fail(ctx != NULL, 1);
566 /* Collect own arguments */
567 GSList *fl = sp_process_args(ctx);
568 poptFreeContext(ctx);
570 // now switch gettext back to UTF-8 (for GUI)
571 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
573 // Now let's see if the file list still holds up
574 if ( needToRecodeParams )
575 {
576 fl = fixupFilenameEncoding( fl );
577 }
579 // Check the globals for filename-fixup
580 if ( needToRecodeParams )
581 {
582 fixupSingleFilename( &sp_export_png, &sp_export_png_utf8 );
583 fixupSingleFilename( &sp_export_svg, &sp_export_svg_utf8 );
584 fixupSingleFilename( &sp_global_printer, &sp_global_printer_utf8 );
585 }
586 else
587 {
588 if ( sp_export_png )
589 sp_export_png_utf8 = g_strdup( sp_export_png );
590 if ( sp_export_svg )
591 sp_export_svg_utf8 = g_strdup( sp_export_svg );
592 if ( sp_global_printer )
593 sp_global_printer_utf8 = g_strdup( sp_global_printer );
594 }
596 // Return the list if wanted, else free it up.
597 if ( flDest ) {
598 *flDest = fl;
599 fl = 0;
600 } else {
601 while ( fl ) {
602 g_free( fl->data );
603 fl = g_slist_remove( fl, fl->data );
604 }
605 }
606 return 0;
607 }
609 int
610 sp_main_gui(int argc, char const **argv)
611 {
612 Gtk::Main main_instance (&argc, const_cast<char ***>(&argv));
614 GSList *fl = NULL;
615 int retVal = sp_common_main( argc, argv, &fl );
616 g_return_val_if_fail(retVal == 0, 1);
618 inkscape_gtk_stock_init();
620 /* Set default icon */
621 gchar *filename = (gchar *) g_build_filename (INKSCAPE_APPICONDIR, "inkscape.png", NULL);
622 if (Inkscape::IO::file_test(filename, (GFileTest)(G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK))) {
623 gtk_window_set_default_icon_from_file(filename, NULL);
624 }
625 g_free (filename);
626 filename = 0;
628 if (!sp_global_slideshow) {
629 gboolean create_new = TRUE;
631 /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
632 inkscape_application_init(argv[0], true);
634 while (fl) {
635 if (sp_file_open((gchar *)fl->data,NULL)) {
636 create_new=FALSE;
637 }
638 fl = g_slist_remove(fl, fl->data);
639 }
640 if (create_new) {
641 sp_file_new_default();
642 }
643 } else {
644 if (fl) {
645 GtkWidget *ss;
646 /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
647 inkscape_application_init(argv[0], true);
648 ss = sp_slideshow_new(fl);
649 if (ss) gtk_widget_show(ss);
650 } else {
651 g_warning ("No slides to display");
652 exit(0);
653 }
654 }
656 main_instance.run();
658 #ifdef WIN32
659 //We might not need anything here
660 //sp_win32_finish(); <-- this is a NOP func
661 #endif
663 return 0;
664 }
666 int
667 sp_main_console(int argc, char const **argv)
668 {
669 /* We are started in text mode */
671 /* Do this g_type_init(), so that we can use Xft/Freetype2 (Pango)
672 * in a non-Gtk environment. Used in libnrtype's
673 * FontInstance.cpp and FontFactory.cpp.
674 * http://mail.gnome.org/archives/gtk-list/2003-December/msg00063.html
675 */
676 g_type_init();
677 char **argv2 = const_cast<char **>(argv);
678 gtk_init_check( &argc, &argv2 );
679 //setlocale(LC_ALL, "");
681 GSList *fl = NULL;
682 int retVal = sp_common_main( argc, argv, &fl );
683 g_return_val_if_fail(retVal == 0, 1);
685 if (fl == NULL) {
686 g_print("Nothing to do!\n");
687 exit(0);
688 }
690 inkscape_application_init(argv[0], false);
692 while (fl) {
693 SPDocument *doc;
695 doc = Inkscape::Extension::open(NULL, (gchar *)fl->data);
696 if (doc == NULL) {
697 doc = Inkscape::Extension::open(Inkscape::Extension::db.get(SP_MODULE_KEY_INPUT_SVG), (gchar *)fl->data);
698 }
699 if (doc == NULL) {
700 g_warning("Specified document %s cannot be opened (is it valid SVG file?)", (gchar *) fl->data);
701 } else {
702 if (sp_vacuum_defs) {
703 vacuum_document(doc);
704 }
705 if (sp_vacuum_defs && !sp_export_svg) {
706 // save under the name given in the command line
707 sp_repr_save_file(doc->rdoc, (gchar *)fl->data, SP_SVG_NS_URI);
708 }
709 if (sp_global_printer) {
710 sp_print_document_to_file(doc, sp_global_printer);
711 }
712 if (sp_export_png || sp_export_id || sp_export_area_drawing) {
713 sp_do_export_png(doc);
714 }
715 if (sp_export_svg) {
716 Inkscape::XML::Document *rdoc;
717 Inkscape::XML::Node *repr;
718 rdoc = sp_repr_document_new("svg:svg");
719 repr = rdoc->root();
720 repr = sp_document_root(doc)->updateRepr(repr, SP_OBJECT_WRITE_BUILD);
721 sp_repr_save_file(repr->document(), sp_export_svg, SP_SVG_NS_URI);
722 }
723 if (sp_export_ps) {
724 do_export_ps(doc, sp_export_ps, "image/x-postscript");
725 }
726 if (sp_export_eps) {
727 do_export_ps(doc, sp_export_eps, "image/x-e-postscript");
728 }
729 if (sp_export_pdf) {
730 do_export_pdf(doc, sp_export_pdf, "application/pdf");
731 }
732 if (sp_query_width || sp_query_height) {
733 do_query_dimension (doc, true, sp_query_width? NR::X : NR::Y, sp_query_id);
734 } else if (sp_query_x || sp_query_y) {
735 do_query_dimension (doc, false, sp_query_x? NR::X : NR::Y, sp_query_id);
736 }
737 }
738 fl = g_slist_remove(fl, fl->data);
739 }
741 inkscape_unref();
743 return 0;
744 }
746 static void
747 do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gchar *id)
748 {
749 SPObject *o = NULL;
751 if (id) {
752 o = doc->getObjectById(id);
753 if (o) {
754 if (!SP_IS_ITEM (o)) {
755 g_warning("Object with id=\"%s\" is not a visible item. Cannot query dimensions.", id);
756 return;
757 }
758 } else {
759 g_warning("Object with id=\"%s\" is not found. Cannot query dimensions.", id);
760 return;
761 }
762 } else {
763 o = SP_DOCUMENT_ROOT(doc);
764 }
766 if (o) {
767 sp_document_ensure_up_to_date (doc);
768 SPItem *item = ((SPItem *) o);
769 NR::Rect area = item->invokeBbox(sp_item_i2doc_affine(item)); // "true" SVG bbox for scripting
771 Inkscape::SVGOStringStream os;
772 if (extent) {
773 os << area.extent(axis);
774 } else {
775 os << area.min()[axis];
776 }
777 g_print ("%s", os.str().c_str());
778 }
779 }
782 static void
783 sp_do_export_png(SPDocument *doc)
784 {
785 const gchar *filename = NULL;
786 gdouble dpi = 0.0;
788 if (sp_export_use_hints && (!sp_export_id && !sp_export_area_drawing)) {
789 g_warning ("--export-use-hints can only be used with --export-id or --export-area-drawing; ignored.");
790 }
792 GSList *items = NULL;
794 NRRect area;
795 if (sp_export_id || sp_export_area_drawing) {
797 SPObject *o = NULL;
798 SPObject *o_area = NULL;
799 if (sp_export_id && sp_export_area_drawing) {
800 o = doc->getObjectById(sp_export_id);
801 o_area = SP_DOCUMENT_ROOT (doc);
802 } else if (sp_export_id) {
803 o = doc->getObjectById(sp_export_id);
804 o_area = o;
805 } else if (sp_export_area_drawing) {
806 o = SP_DOCUMENT_ROOT (doc);
807 o_area = o;
808 }
810 if (o) {
811 if (!SP_IS_ITEM (o)) {
812 g_warning("Object with id=\"%s\" is not a visible item. Nothing exported.", sp_export_id);
813 return;
814 }
816 items = g_slist_prepend (items, SP_ITEM(o));
818 if (sp_export_id_only) {
819 g_print("Exporting only object with id=\"%s\"; all other objects hidden\n", sp_export_id);
820 }
822 if (sp_export_use_hints) {
824 // retrieve export filename hint
825 const gchar *fn_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-filename");
826 if (fn_hint) {
827 if (sp_export_png) {
828 g_warning ("Using export filename from the command line (--export-png). Filename hint %s is ignored.", fn_hint);
829 filename = sp_export_png;
830 } else {
831 filename = fn_hint;
832 }
833 } else {
834 g_warning ("Export filename hint not found for the object.");
835 filename = sp_export_png;
836 }
838 // retrieve export dpi hints
839 const gchar *dpi_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-xdpi"); // only xdpi, ydpi is always the same now
840 if (dpi_hint) {
841 if (sp_export_dpi || sp_export_width || sp_export_height) {
842 g_warning ("Using bitmap dimensions from the command line (--export-dpi, --export-width, or --export-height). DPI hint %s is ignored.", dpi_hint);
843 } else {
844 dpi = atof(dpi_hint);
845 }
846 } else {
847 g_warning ("Export DPI hint not found for the object.");
848 }
850 }
852 // write object bbox to area
853 sp_document_ensure_up_to_date (doc);
854 sp_item_invoke_bbox((SPItem *) o_area, &area, sp_item_i2r_affine((SPItem *) o_area), TRUE);
855 } else {
856 g_warning("Object with id=\"%s\" was not found in the document. Nothing exported.", sp_export_id);
857 return;
858 }
859 }
861 if (sp_export_area) {
862 /* Try to parse area (given in SVG pixels) */
863 if (!sscanf(sp_export_area, "%lg:%lg:%lg:%lg", &area.x0, &area.y0, &area.x1, &area.y1) == 4) {
864 g_warning("Cannot parse export area '%s'; use 'x0:y0:x1:y1'. Nothing exported.", sp_export_area);
865 return;
866 }
867 if ((area.x0 >= area.x1) || (area.y0 >= area.y1)) {
868 g_warning("Export area '%s' has negative width or height. Nothing exported.", sp_export_area);
869 return;
870 }
871 } else if (sp_export_area_canvas || !(sp_export_id || sp_export_area_drawing)) {
872 /* Export the whole canvas */
873 sp_document_ensure_up_to_date (doc);
874 area.x0 = SP_ROOT(doc->root)->x.computed;
875 area.y0 = SP_ROOT(doc->root)->y.computed;
876 area.x1 = area.x0 + sp_document_width (doc);
877 area.y1 = area.y0 + sp_document_height (doc);
878 }
880 // set filename and dpi from options, if not yet set from the hints
881 if (!filename) {
882 if (!sp_export_png) {
883 g_warning ("No export filename given and no filename hint. Nothing exported.");
884 return;
885 }
886 filename = sp_export_png;
887 }
889 if (sp_export_dpi && dpi == 0.0) {
890 dpi = atof(sp_export_dpi);
891 if ((dpi < 0.1) || (dpi > 10000.0)) {
892 g_warning("DPI value %s out of range [0.1 - 10000.0]. Nothing exported.", sp_export_dpi);
893 return;
894 }
895 g_print("DPI: %g\n", dpi);
896 }
898 if (sp_export_area_snap) {
899 area.x0 = std::floor (area.x0);
900 area.y0 = std::floor (area.y0);
901 area.x1 = std::ceil (area.x1);
902 area.y1 = std::ceil (area.y1);
903 }
905 // default dpi
906 if (dpi == 0.0)
907 dpi = PX_PER_IN;
909 gint width = 0;
910 gint height = 0;
912 if (sp_export_width) {
913 width = atoi(sp_export_width);
914 if ((width < 1) || (width > 65536)) {
915 g_warning("Export width %d out of range (1 - 65536). Nothing exported.", width);
916 return;
917 }
918 dpi = (gdouble) width * PX_PER_IN / (area.x1 - area.x0);
919 }
921 if (sp_export_height) {
922 height = atoi(sp_export_height);
923 if ((height < 1) || (height > 65536)) {
924 g_warning("Export height %d out of range (1 - 65536). Nothing exported.", width);
925 return;
926 }
927 dpi = (gdouble) height * PX_PER_IN / (area.y1 - area.y0);
928 }
930 if (!sp_export_width) {
931 width = (gint) ((area.x1 - area.x0) * dpi / PX_PER_IN + 0.5);
932 }
934 if (!sp_export_height) {
935 height = (gint) ((area.y1 - area.y0) * dpi / PX_PER_IN + 0.5);
936 }
938 guint32 bgcolor = 0x00000000;
939 if (sp_export_background) {
940 // override the page color
941 bgcolor = sp_svg_read_color(sp_export_background, 0xffffff00);
942 bgcolor |= 0xff; // default is no opacity
943 } else {
944 // read from namedview
945 Inkscape::XML::Node *nv = sp_repr_lookup_name (doc->rroot, "sodipodi:namedview");
946 if (nv && nv->attribute("pagecolor"))
947 bgcolor = sp_svg_read_color(nv->attribute("pagecolor"), 0xffffff00);
948 if (nv && nv->attribute("inkscape:pageopacity"))
949 bgcolor |= SP_COLOR_F_TO_U(sp_repr_get_double_attribute (nv, "inkscape:pageopacity", 1.0));
950 }
952 if (sp_export_background_opacity) {
953 // override opacity
954 gfloat value;
955 if (sp_svg_number_read_f (sp_export_background_opacity, &value)) {
956 if (value > 1.0) {
957 value = CLAMP (value, 1.0f, 255.0f);
958 bgcolor &= (guint32) 0xffffff00;
959 bgcolor |= (guint32) floor(value);
960 } else {
961 value = CLAMP (value, 0.0f, 1.0f);
962 bgcolor &= (guint32) 0xffffff00;
963 bgcolor |= SP_COLOR_F_TO_U(value);
964 }
965 }
966 }
968 g_print("Background RRGGBBAA: %08x\n", bgcolor);
970 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);
972 g_print("Bitmap saved as: %s\n", filename);
974 if ((width >= 1) && (height >= 1) && (width < 65536) && (height < 65536)) {
975 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);
976 } else {
977 g_warning("Calculated bitmap dimensions %d %d are out of range (1 - 65535). Nothing exported.", width, height);
978 }
980 g_slist_free (items);
981 }
984 /**
985 * Perform an export of either PS or EPS.
986 *
987 * \param doc Document to export.
988 * \param uri URI to export to.
989 * \param mime MIME type to export as.
990 */
992 static void do_export_ps(SPDocument* doc, gchar const* uri, char const* mime)
993 {
994 Inkscape::Extension::DB::OutputList o;
995 Inkscape::Extension::db.get_output_list(o);
996 Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
997 while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
998 i++;
999 }
1001 if (i == o.end())
1002 {
1003 g_warning ("Could not find an extension to export this file.");
1004 return;
1005 }
1007 bool old_text_to_path = false;
1008 bool old_font_embedded = false;
1009 bool old_bbox_page = false;
1011 try {
1012 old_text_to_path = (*i)->get_param_bool("textToPath");
1013 (*i)->set_param_bool("textToPath", sp_export_text_to_path);
1014 }
1015 catch (...) {
1016 g_warning ("Could not set export-text-to-path option for this export.");
1017 }
1019 try {
1020 old_font_embedded = (*i)->get_param_bool("fontEmbedded");
1021 (*i)->set_param_bool("fontEmbedded", sp_export_font);
1022 }
1023 catch (...) {
1024 g_warning ("Could not set export-font option for this export.");
1025 }
1027 try {
1028 old_bbox_page = (*i)->get_param_bool("pageBoundingBox");
1029 (*i)->set_param_bool("pageBoundingBox", sp_export_bbox_page);
1030 }
1031 catch (...) {
1032 g_warning ("Could not set export-bbox-page option for this export.");
1033 }
1035 (*i)->save(doc, uri);
1037 try {
1038 (*i)->set_param_bool("textToPath", old_text_to_path);
1039 (*i)->set_param_bool("fontEmbedded", old_font_embedded);
1040 (*i)->set_param_bool("pageBoundingBox", old_bbox_page);
1041 }
1042 catch (...) {
1044 }
1045 }
1047 /**
1048 * Perform a PDF export
1049 *
1050 * \param doc Document to export.
1051 * \param uri URI to export to.
1052 * \param mime MIME type to export as.
1053 */
1055 static void do_export_pdf(SPDocument* doc, gchar const* uri, char const* mime)
1056 {
1057 Inkscape::Extension::DB::OutputList o;
1058 Inkscape::Extension::db.get_output_list(o);
1059 Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
1060 while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
1061 i++;
1062 }
1064 if (i == o.end())
1065 {
1066 g_warning ("Could not find an extension to export this file.");
1067 return;
1068 }
1070 (*i)->save(doc, uri);
1071 }
1073 #ifdef WIN32
1074 bool replaceArgs( int& argc, char**& argv )
1075 {
1076 bool worked = false;
1078 #ifdef REPLACEARGS_DEBUG
1079 MessageBoxA( NULL, "GetCommandLineW() getting called", "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1080 #endif // REPLACEARGS_DEBUG
1082 wchar_t* line = GetCommandLineW();
1083 if ( line )
1084 {
1085 #ifdef REPLACEARGS_DEBUG
1086 {
1087 gchar* utf8Line = g_utf16_to_utf8( (gunichar2*)line, -1, NULL, NULL, NULL );
1088 if ( utf8Line )
1089 {
1090 gchar *safe = Inkscape::IO::sanitizeString(utf8Line);
1091 {
1092 char tmp[strlen(safe) + 32];
1093 snprintf( tmp, sizeof(tmp), "GetCommandLineW() = '%s'", safe );
1094 MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1095 }
1096 }
1097 }
1098 #endif // REPLACEARGS_DEBUG
1100 int numArgs = 0;
1101 wchar_t** parsed = CommandLineToArgvW( line, &numArgs );
1103 #ifdef REPLACEARGS_ANSI
1104 // test code for trying things on Win95/98/ME
1105 if ( !parsed )
1106 {
1107 #ifdef REPLACEARGS_DEBUG
1108 MessageBoxA( NULL, "Unable to process command-line. Faking it", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1109 #endif // REPLACEARGS_DEBUG
1110 int lineLen = wcslen(line) + 1;
1111 wchar_t* lineDup = new wchar_t[lineLen];
1112 wcsncpy( lineDup, line, lineLen );
1114 int pos = 0;
1115 bool inQuotes = false;
1116 bool inWhitespace = true;
1117 std::vector<int> places;
1118 while ( lineDup[pos] )
1119 {
1120 if ( inQuotes )
1121 {
1122 if ( lineDup[pos] == L'"' )
1123 {
1124 inQuotes = false;
1125 }
1126 }
1127 else if ( lineDup[pos] == L'"' )
1128 {
1129 inQuotes = true;
1130 inWhitespace = false;
1131 places.push_back(pos);
1132 }
1133 else if ( lineDup[pos] == L' ' || lineDup[pos] == L'\t' )
1134 {
1135 if ( !inWhitespace )
1136 {
1137 inWhitespace = true;
1138 lineDup[pos] = 0;
1139 }
1140 }
1141 else if ( inWhitespace && (lineDup[pos] != L' ' && lineDup[pos] != L'\t') )
1142 {
1143 inWhitespace = false;
1144 places.push_back(pos);
1145 }
1146 else
1147 {
1148 // consume
1149 }
1150 pos++;
1151 }
1152 #ifdef REPLACEARGS_DEBUG
1153 {
1154 char tmp[256];
1155 snprintf( tmp, sizeof(tmp), "Counted %d args", places.size() );
1156 MessageBoxA( NULL, tmp, "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1157 }
1158 #endif // REPLACEARGS_DEBUG
1160 wchar_t** block = new wchar_t*[places.size()];
1161 int i = 0;
1162 for ( std::vector<int>::iterator it = places.begin(); it != places.end(); it++ )
1163 {
1164 block[i++] = &lineDup[*it];
1165 }
1166 parsed = block;
1167 numArgs = places.size();
1168 }
1169 #endif // REPLACEARGS_ANSI
1171 if ( parsed )
1172 {
1173 std::vector<wchar_t*>expandedArgs;
1174 if ( numArgs > 0 )
1175 {
1176 expandedArgs.push_back( parsed[0] );
1177 }
1179 for ( int i1 = 1; i1 < numArgs; i1++ )
1180 {
1181 bool wildcarded = (wcschr(parsed[i1], L'?') != NULL) || (wcschr(parsed[i1], L'*') != NULL);
1182 wildcarded &= parsed[i1][0] != L'"';
1183 wildcarded &= parsed[i1][0] != L'-';
1184 if ( wildcarded )
1185 {
1186 #ifdef REPLACEARGS_ANSI
1187 WIN32_FIND_DATAA data = {0};
1188 #else
1189 WIN32_FIND_DATAW data = {0};
1190 #endif // REPLACEARGS_ANSI
1192 int baseLen = wcslen(parsed[i1]) + 2;
1193 wchar_t* base = new wchar_t[baseLen];
1194 wcsncpy( base, parsed[i1], baseLen );
1195 wchar_t* last = wcsrchr( base, L'\\' );
1196 if ( last )
1197 {
1198 last[1] = 0;
1199 }
1200 else
1201 {
1202 base[0] = 0;
1203 }
1204 baseLen = wcslen( base );
1206 #ifdef REPLACEARGS_ANSI
1207 char target[MAX_PATH];
1208 if ( WideCharToMultiByte( CP_ACP, 0, parsed[i1], -1, target, sizeof(target), NULL, NULL) )
1209 {
1210 HANDLE hf = FindFirstFileA( target, &data );
1211 #else
1212 HANDLE hf = FindFirstFileW( parsed[i1], &data );
1213 #endif // REPLACEARGS_ANSI
1214 if ( hf != INVALID_HANDLE_VALUE )
1215 {
1216 BOOL found = TRUE;
1217 do
1218 {
1219 #ifdef REPLACEARGS_ANSI
1220 int howMany = MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, NULL, 0 );
1221 if ( howMany > 0 )
1222 {
1223 howMany += baseLen;
1224 wchar_t* tmp = new wchar_t[howMany + 1];
1225 wcsncpy( tmp, base, howMany + 1 );
1226 MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, tmp + baseLen, howMany + 1 - baseLen );
1227 expandedArgs.push_back( tmp );
1228 found = FindNextFileA( hf, &data );
1229 }
1230 #else
1231 int howMany = wcslen(data.cFileName) + baseLen;
1232 wchar_t* tmp = new wchar_t[howMany + 1];
1233 wcsncpy( tmp, base, howMany + 1 );
1234 wcsncat( tmp, data.cFileName, howMany + 1 );
1235 expandedArgs.push_back( tmp );
1236 found = FindNextFileW( hf, &data );
1237 #endif // REPLACEARGS_ANSI
1238 } while ( found );
1240 FindClose( hf );
1241 }
1242 else
1243 {
1244 expandedArgs.push_back( parsed[i1] );
1245 }
1246 #ifdef REPLACEARGS_ANSI
1247 }
1248 #endif // REPLACEARGS_ANSI
1250 delete[] base;
1251 }
1252 else
1253 {
1254 expandedArgs.push_back( parsed[i1] );
1255 }
1256 }
1258 {
1259 wchar_t** block = new wchar_t*[expandedArgs.size()];
1260 int iz = 0;
1261 for ( std::vector<wchar_t*>::iterator it = expandedArgs.begin(); it != expandedArgs.end(); it++ )
1262 {
1263 block[iz++] = *it;
1264 }
1265 parsed = block;
1266 numArgs = expandedArgs.size();
1267 }
1269 std::vector<gchar*> newArgs;
1270 for ( int i = 0; i < numArgs; i++ )
1271 {
1272 gchar* replacement = g_utf16_to_utf8( (gunichar2*)parsed[i], -1, NULL, NULL, NULL );
1273 if ( replacement )
1274 {
1275 #ifdef REPLACEARGS_DEBUG
1276 gchar *safe2 = Inkscape::IO::sanitizeString(replacement);
1278 if ( safe2 )
1279 {
1280 {
1281 char tmp[1024];
1282 snprintf( tmp, sizeof(tmp), " [%2d] = '%s'", i, safe2 );
1283 MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1284 }
1285 g_free( safe2 );
1286 }
1287 #endif // REPLACEARGS_DEBUG
1289 newArgs.push_back( replacement );
1290 }
1291 else
1292 {
1293 newArgs.push_back( blankParam );
1294 }
1295 }
1297 // Now push our munged params to be the new argv and argc
1298 {
1299 char** block = new char*[newArgs.size()];
1300 int iz = 0;
1301 for ( std::vector<char*>::iterator it = newArgs.begin(); it != newArgs.end(); it++ )
1302 {
1303 block[iz++] = *it;
1304 }
1305 argv = block;
1306 argc = newArgs.size();
1307 worked = true;
1308 }
1309 }
1310 #ifdef REPLACEARGS_DEBUG
1311 else
1312 {
1313 MessageBoxA( NULL, "Unable to process command-line", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1314 }
1315 #endif // REPLACEARGS_DEBUG
1316 }
1317 #ifdef REPLACEARGS_DEBUG
1318 else
1319 {
1320 {
1321 MessageBoxA( NULL, "Unable to fetch result from GetCommandLineW()", "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1322 }
1324 char* line2 = GetCommandLineA();
1325 if ( line2 )
1326 {
1327 gchar *safe = Inkscape::IO::sanitizeString(line2);
1328 {
1329 {
1330 char tmp[strlen(safe) + 32];
1331 snprintf( tmp, sizeof(tmp), "GetCommandLineA() = '%s'", safe );
1332 MessageBoxA( NULL, tmp, "GetCommandLineA", MB_OK | MB_ICONINFORMATION );
1333 }
1334 }
1335 }
1336 else
1337 {
1338 MessageBoxA( NULL, "Unable to fetch result from GetCommandLineA()", "GetCommandLineA", MB_OK | MB_ICONINFORMATION );
1339 }
1340 }
1341 #endif // REPLACEARGS_DEBUG
1343 return worked;
1344 }
1345 #endif // WIN32
1347 static GSList *
1348 sp_process_args(poptContext ctx)
1349 {
1350 GSList *fl = NULL;
1352 gint a;
1353 while ((a = poptGetNextOpt(ctx)) >= 0) {
1354 switch (a) {
1355 case SP_ARG_FILE: {
1356 gchar const *fn = poptGetOptArg(ctx);
1357 if (fn != NULL) {
1358 fl = g_slist_append(fl, g_strdup(fn));
1359 }
1360 break;
1361 }
1362 case SP_ARG_VERSION: {
1363 printf("Inkscape %s (%s)\n", INKSCAPE_VERSION, __DATE__);
1364 exit(0);
1365 break;
1366 }
1367 case SP_ARG_EXTENSIONDIR: {
1368 printf("%s\n", INKSCAPE_EXTENSIONDIR);
1369 exit(0);
1370 break;
1371 }
1372 default: {
1373 break;
1374 }
1375 }
1376 }
1378 gchar const ** const args = poptGetArgs(ctx);
1379 if (args != NULL) {
1380 for (unsigned i = 0; args[i] != NULL; i++) {
1381 fl = g_slist_append(fl, g_strdup(args[i]));
1382 }
1383 }
1385 return fl;
1386 }
1389 /*
1390 Local Variables:
1391 mode:c++
1392 c-file-style:"stroustrup"
1393 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
1394 indent-tabs-mode:nil
1395 fill-column:99
1396 End:
1397 */
1398 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :