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 "color.h"
60 #include "sp-item.h"
61 #include "sp-root.h"
62 #include "unit-constants.h"
64 #include "svg/svg.h"
65 #include "svg/svg-color.h"
66 #include "svg/stringstream.h"
68 #include "inkscape-private.h"
69 #include "inkscape-stock.h"
70 #include "inkscape_version.h"
72 #include "sp-namedview.h"
73 #include "sp-guide.h"
74 #include "sp-object-repr.h"
75 #include "xml/repr.h"
77 #include "io/sys.h"
79 #include "debug/logger.h"
81 #include "helper/png-write.h"
83 #include <extension/extension.h>
84 #include <extension/system.h>
85 #include <extension/db.h>
86 #include <extension/output.h>
88 #ifdef WIN32
89 //#define REPLACEARGS_ANSI
90 //#define REPLACEARGS_DEBUG
92 #include "registrytool.h"
94 #include "extension/internal/win32.h"
95 using Inkscape::Extension::Internal::PrintWin32;
97 #endif // WIN32
99 #include "extension/init.h"
101 #include <glibmm/i18n.h>
102 #include <gtkmm/main.h>
104 #ifndef HAVE_BIND_TEXTDOMAIN_CODESET
105 #define bind_textdomain_codeset(p,c)
106 #endif
108 #include "application/application.h"
110 #include "main-cmdlineact.h"
112 enum {
113 SP_ARG_NONE,
114 SP_ARG_NOGUI,
115 SP_ARG_GUI,
116 SP_ARG_FILE,
117 SP_ARG_PRINT,
118 SP_ARG_EXPORT_PNG,
119 SP_ARG_EXPORT_DPI,
120 SP_ARG_EXPORT_AREA,
121 SP_ARG_EXPORT_AREA_DRAWING,
122 SP_ARG_EXPORT_AREA_CANVAS,
123 SP_ARG_EXPORT_AREA_SNAP,
124 SP_ARG_EXPORT_WIDTH,
125 SP_ARG_EXPORT_HEIGHT,
126 SP_ARG_EXPORT_ID,
127 SP_ARG_EXPORT_ID_ONLY,
128 SP_ARG_EXPORT_USE_HINTS,
129 SP_ARG_EXPORT_BACKGROUND,
130 SP_ARG_EXPORT_BACKGROUND_OPACITY,
131 SP_ARG_EXPORT_SVG,
132 SP_ARG_EXPORT_PS,
133 SP_ARG_EXPORT_EPS,
134 SP_ARG_EXPORT_PDF,
135 SP_ARG_EXPORT_TEXT_TO_PATH,
136 SP_ARG_EXPORT_FONT,
137 SP_ARG_EXPORT_BBOX_PAGE,
138 SP_ARG_EXTENSIONDIR,
139 SP_ARG_FIT_PAGE_TO_DRAWING,
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_VERB_LIST,
148 SP_ARG_VERB,
149 SP_ARG_SELECT,
150 SP_ARG_LAST
151 };
153 int sp_main_gui(int argc, char const **argv);
154 int sp_main_console(int argc, char const **argv);
155 static void sp_do_export_png(SPDocument *doc);
156 static void do_export_ps(SPDocument* doc, gchar const* uri, char const *mime);
157 static void do_export_pdf(SPDocument* doc, gchar const* uri, char const *mime);
158 static void do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gchar *id);
161 static gchar *sp_global_printer = NULL;
162 static gchar *sp_export_png = NULL;
163 static gchar *sp_export_dpi = NULL;
164 static gchar *sp_export_area = NULL;
165 static gboolean sp_export_area_drawing = FALSE;
166 static gboolean sp_export_area_canvas = FALSE;
167 static gchar *sp_export_width = NULL;
168 static gchar *sp_export_height = NULL;
169 static gchar *sp_export_id = NULL;
170 static gchar *sp_export_background = NULL;
171 static gchar *sp_export_background_opacity = NULL;
172 static gboolean sp_export_area_snap = FALSE;
173 static gboolean sp_export_use_hints = FALSE;
174 static gboolean sp_export_id_only = FALSE;
175 static gchar *sp_export_svg = NULL;
176 static gchar *sp_export_ps = NULL;
177 static gchar *sp_export_eps = NULL;
178 static gchar *sp_export_pdf = NULL;
179 static gboolean sp_export_text_to_path = FALSE;
180 static gboolean sp_export_font = FALSE;
181 static gboolean sp_export_bbox_page = FALSE;
182 static gboolean sp_query_x = FALSE;
183 static gboolean sp_query_y = FALSE;
184 static gboolean sp_query_width = FALSE;
185 static gboolean sp_query_height = FALSE;
186 static gchar *sp_query_id = NULL;
187 static int sp_new_gui = FALSE;
188 static gboolean sp_vacuum_defs = FALSE;
190 static gchar *sp_export_png_utf8 = NULL;
191 static gchar *sp_export_svg_utf8 = NULL;
192 static gchar *sp_global_printer_utf8 = NULL;
194 #ifdef WIN32
195 static bool replaceArgs( int& argc, char**& argv );
196 #endif
197 static GSList *sp_process_args(poptContext ctx);
198 struct poptOption options[] = {
199 {"version", 'V',
200 POPT_ARG_NONE, NULL, SP_ARG_VERSION,
201 N_("Print the Inkscape version number"),
202 NULL},
204 {"without-gui", 'z',
205 POPT_ARG_NONE, NULL, SP_ARG_NOGUI,
206 N_("Do not use X server (only process files from console)"),
207 NULL},
209 {"with-gui", 'g',
210 POPT_ARG_NONE, NULL, SP_ARG_GUI,
211 N_("Try to use X server (even if $DISPLAY is not set)"),
212 NULL},
214 {"file", 'f',
215 POPT_ARG_STRING, NULL, SP_ARG_FILE,
216 N_("Open specified document(s) (option string may be excluded)"),
217 N_("FILENAME")},
219 {"print", 'p',
220 POPT_ARG_STRING, &sp_global_printer, SP_ARG_PRINT,
221 N_("Print document(s) to specified output file (use '| program' for pipe)"),
222 N_("FILENAME")},
224 {"export-png", 'e',
225 POPT_ARG_STRING, &sp_export_png, SP_ARG_EXPORT_PNG,
226 N_("Export document to a PNG file"),
227 N_("FILENAME")},
229 {"export-dpi", 'd',
230 POPT_ARG_STRING, &sp_export_dpi, SP_ARG_EXPORT_DPI,
231 N_("The resolution used for exporting SVG into bitmap (default 90)"),
232 N_("DPI")},
234 {"export-area", 'a',
235 POPT_ARG_STRING, &sp_export_area, SP_ARG_EXPORT_AREA,
236 N_("Exported area in SVG user units (default is the canvas; 0,0 is lower-left corner)"),
237 N_("x0:y0:x1:y1")},
239 {"export-area-drawing", 'D',
240 POPT_ARG_NONE, &sp_export_area_drawing, SP_ARG_EXPORT_AREA_DRAWING,
241 N_("Exported area is the entire drawing (not canvas)"),
242 NULL},
244 {"export-area-canvas", 'C',
245 POPT_ARG_NONE, &sp_export_area_canvas, SP_ARG_EXPORT_AREA_CANVAS,
246 N_("Exported area is the entire canvas"),
247 NULL},
249 {"export-area-snap", 0,
250 POPT_ARG_NONE, &sp_export_area_snap, SP_ARG_EXPORT_AREA_SNAP,
251 N_("Snap the bitmap export area outwards to the nearest integer values (in SVG user units)"),
252 NULL},
254 {"export-width", 'w',
255 POPT_ARG_STRING, &sp_export_width, SP_ARG_EXPORT_WIDTH,
256 N_("The width of exported bitmap in pixels (overrides export-dpi)"),
257 N_("WIDTH")},
259 {"export-height", 'h',
260 POPT_ARG_STRING, &sp_export_height, SP_ARG_EXPORT_HEIGHT,
261 N_("The height of exported bitmap in pixels (overrides export-dpi)"),
262 N_("HEIGHT")},
264 {"export-id", 'i',
265 POPT_ARG_STRING, &sp_export_id, SP_ARG_EXPORT_ID,
266 N_("The ID of the object to export"),
267 N_("ID")},
269 {"export-id-only", 'j',
270 POPT_ARG_NONE, &sp_export_id_only, SP_ARG_EXPORT_ID_ONLY,
271 // TRANSLATORS: this means: "Only export the object whose id is given in --export-id".
272 // See "man inkscape" for details.
273 N_("Export just the object with export-id, hide all others (only with export-id)"),
274 NULL},
276 {"export-use-hints", 't',
277 POPT_ARG_NONE, &sp_export_use_hints, SP_ARG_EXPORT_USE_HINTS,
278 N_("Use stored filename and DPI hints when exporting (only with export-id)"),
279 NULL},
281 {"export-background", 'b',
282 POPT_ARG_STRING, &sp_export_background, SP_ARG_EXPORT_BACKGROUND,
283 N_("Background color of exported bitmap (any SVG-supported color string)"),
284 N_("COLOR")},
286 {"export-background-opacity", 'y',
287 POPT_ARG_STRING, &sp_export_background_opacity, SP_ARG_EXPORT_BACKGROUND_OPACITY,
288 N_("Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)"),
289 N_("VALUE")},
291 {"export-plain-svg", 'l',
292 POPT_ARG_STRING, &sp_export_svg, SP_ARG_EXPORT_SVG,
293 N_("Export document to plain SVG file (no sodipodi or inkscape namespaces)"),
294 N_("FILENAME")},
296 {"export-ps", 'P',
297 POPT_ARG_STRING, &sp_export_ps, SP_ARG_EXPORT_PS,
298 N_("Export document to a PS file"),
299 N_("FILENAME")},
301 {"export-eps", 'E',
302 POPT_ARG_STRING, &sp_export_eps, SP_ARG_EXPORT_EPS,
303 N_("Export document to an EPS file"),
304 N_("FILENAME")},
306 {"export-pdf", 'A',
307 POPT_ARG_STRING, &sp_export_pdf, SP_ARG_EXPORT_PDF,
308 N_("Export document to a PDF file"),
309 N_("FILENAME")},
311 {"export-text-to-path", 'T',
312 POPT_ARG_NONE, &sp_export_text_to_path, SP_ARG_EXPORT_TEXT_TO_PATH,
313 N_("Convert text object to paths on export (EPS)"),
314 NULL},
316 {"export-embed-fonts", 'F',
317 POPT_ARG_NONE, &sp_export_font, SP_ARG_EXPORT_FONT,
318 N_("Embed fonts on export (Type 1 only) (EPS)"),
319 NULL},
321 {"export-bbox-page", 'B',
322 POPT_ARG_NONE, &sp_export_bbox_page, SP_ARG_EXPORT_BBOX_PAGE,
323 N_("Export files with the bounding box set to the page size (EPS)"),
324 NULL},
326 {"query-x", 'X',
327 POPT_ARG_NONE, &sp_query_x, SP_ARG_QUERY_X,
328 // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
329 N_("Query the X coordinate of the drawing or, if specified, of the object with --query-id"),
330 NULL},
332 {"query-y", 'Y',
333 POPT_ARG_NONE, &sp_query_y, SP_ARG_QUERY_Y,
334 // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
335 N_("Query the Y coordinate of the drawing or, if specified, of the object with --query-id"),
336 NULL},
338 {"query-width", 'W',
339 POPT_ARG_NONE, &sp_query_width, SP_ARG_QUERY_WIDTH,
340 // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
341 N_("Query the width of the drawing or, if specified, of the object with --query-id"),
342 NULL},
344 {"query-height", 'H',
345 POPT_ARG_NONE, &sp_query_height, SP_ARG_QUERY_HEIGHT,
346 // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
347 N_("Query the height of the drawing or, if specified, of the object with --query-id"),
348 NULL},
350 {"query-id", 'I',
351 POPT_ARG_STRING, &sp_query_id, SP_ARG_QUERY_ID,
352 N_("The ID of the object whose dimensions are queried"),
353 N_("ID")},
355 {"extension-directory", 'x',
356 POPT_ARG_NONE, NULL, SP_ARG_EXTENSIONDIR,
357 // TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory
358 N_("Print out the extension directory and exit"),
359 NULL},
361 {"vacuum-defs", 0,
362 POPT_ARG_NONE, &sp_vacuum_defs, SP_ARG_VACUUM_DEFS,
363 N_("Remove unused definitions from the defs section(s) of the document"),
364 NULL},
366 {"verb-list", 0,
367 POPT_ARG_NONE, NULL, SP_ARG_VERB_LIST,
368 N_("List the IDs of all the verbs in Inkscape"),
369 NULL},
371 {"verb", 0,
372 POPT_ARG_STRING, NULL, SP_ARG_VERB,
373 N_("Verb to call when Inkscape opens."),
374 N_("VERB-ID")},
376 {"select", 0,
377 POPT_ARG_STRING, NULL, SP_ARG_SELECT,
378 N_("Object ID to select when Inkscape opens."),
379 N_("OBJECT-ID")},
381 POPT_AUTOHELP POPT_TABLEEND
382 };
384 static bool needToRecodeParams = true;
385 gchar* blankParam = "";
387 int
388 main(int argc, char **argv)
389 {
390 #ifdef HAVE_FPSETMASK
391 /* This is inherited from Sodipodi code, where it was in #ifdef __FreeBSD__. It's probably
392 safe to remove: the default mask is already 0 in C99, and in current FreeBSD according to
393 the fenv man page on www.freebsd.org, and in glibc according to (libc)FP Exceptions. */
394 fpsetmask(fpgetmask() & ~(FP_X_DZ | FP_X_INV));
395 #endif
397 #ifdef ENABLE_NLS
398 #ifdef WIN32
399 RegistryTool rt;
400 rt.setPathInfo();
401 gchar *pathBuf = g_strconcat(g_path_get_dirname(argv[0]), "\\", PACKAGE_LOCALE_DIR, NULL);
402 bindtextdomain(GETTEXT_PACKAGE, pathBuf);
403 g_free(pathBuf);
404 #else
405 #ifdef ENABLE_BINRELOC
406 bindtextdomain(GETTEXT_PACKAGE, BR_LOCALEDIR(""));
407 #else
408 bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
409 #endif
410 #endif
411 // Allow the user to override the locale directory by setting
412 // the environment variable INKSCAPE_LOCALEDIR.
413 char *inkscape_localedir = getenv("INKSCAPE_LOCALEDIR");
414 if (inkscape_localedir != NULL) {
415 bindtextdomain(GETTEXT_PACKAGE, inkscape_localedir);
416 }
417 #endif
419 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
421 #ifdef ENABLE_NLS
422 textdomain(GETTEXT_PACKAGE);
423 #endif
425 LIBXML_TEST_VERSION
427 Inkscape::GC::init();
429 Inkscape::Debug::Logger::init();
431 gboolean use_gui;
432 #ifndef WIN32
433 use_gui = (getenv("DISPLAY") != NULL);
434 #else
435 /*
436 Set the current directory to the directory of the
437 executable. This seems redundant, but is needed for
438 when inkscape.exe is executed from another directory.
439 We use relative paths on win32.
440 HKCR\svgfile\shell\open\command is a good example
441 */
442 /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
443 char *homedir = g_path_get_dirname(argv[0]);
444 SetCurrentDirectory(homedir);
445 g_free(homedir);
447 use_gui = TRUE;
448 #endif
449 /* Test whether with/without GUI is forced */
450 for (int i = 1; i < argc; i++) {
451 if (!strcmp(argv[i], "-z")
452 || !strcmp(argv[i], "--without-gui")
453 || !strcmp(argv[i], "-p")
454 || !strncmp(argv[i], "--print", 7)
455 || !strcmp(argv[i], "-e")
456 || !strncmp(argv[i], "--export-png", 12)
457 || !strcmp(argv[i], "-l")
458 || !strncmp(argv[i], "--export-plain-svg", 12)
459 || !strcmp(argv[i], "-i")
460 || !strncmp(argv[i], "--export-area-drawing", 21)
461 || !strcmp(argv[i], "-D")
462 || !strncmp(argv[i], "--export-area-canvas", 20)
463 || !strcmp(argv[i], "-C")
464 || !strncmp(argv[i], "--export-id", 12)
465 || !strcmp(argv[i], "-P")
466 || !strncmp(argv[i], "--export-ps", 11)
467 || !strcmp(argv[i], "-E")
468 || !strncmp(argv[i], "--export-eps", 12)
469 || !strcmp(argv[i], "-A")
470 || !strncmp(argv[i], "--export-pdf", 12)
471 || !strcmp(argv[i], "-W")
472 || !strncmp(argv[i], "--query-width", 13)
473 || !strcmp(argv[i], "-H")
474 || !strncmp(argv[i], "--query-height", 14)
475 || !strcmp(argv[i], "-X")
476 || !strncmp(argv[i], "--query-x", 13)
477 || !strcmp(argv[i], "-Y")
478 || !strncmp(argv[i], "--query-y", 14)
479 || !strcmp(argv[i], "--vacuum-defs")
480 )
481 {
482 /* main_console handles any exports -- not the gui */
483 use_gui = FALSE;
484 break;
485 } else if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--with-gui")) {
486 use_gui = TRUE;
487 break;
488 }
489 }
491 #ifdef WIN32
492 #ifndef REPLACEARGS_ANSI
493 if ( PrintWin32::is_os_wide() )
494 #endif // REPLACEARGS_ANSI
495 {
496 // If the call fails, we'll need to convert charsets
497 needToRecodeParams = !replaceArgs( argc, argv );
498 }
499 #endif // WIN32
501 /// \todo Should this be a static object (see inkscape.cpp)?
502 Inkscape::NSApplication::Application app(argc, argv, use_gui, sp_new_gui);
504 return app.run();
505 }
507 void fixupSingleFilename( gchar **orig, gchar **spare )
508 {
509 if ( orig && *orig && **orig ) {
510 GError *error = NULL;
511 gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(*orig, -1, NULL, NULL, &error);
512 if ( newFileName )
513 {
514 *orig = newFileName;
515 if ( spare ) {
516 *spare = newFileName;
517 }
518 // g_message("Set a replacement fixup");
519 }
520 }
521 }
523 GSList *fixupFilenameEncoding( GSList* fl )
524 {
525 GSList *newFl = NULL;
526 while ( fl ) {
527 gchar *fn = static_cast<gchar*>(fl->data);
528 fl = g_slist_remove( fl, fl->data );
529 gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(fn, -1, NULL, NULL, NULL);
530 if ( newFileName ) {
532 if ( 0 )
533 {
534 gchar *safeFn = Inkscape::IO::sanitizeString(fn);
535 gchar *safeNewFn = Inkscape::IO::sanitizeString(newFileName);
536 GtkWidget *w = gtk_message_dialog_new( NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
537 "Note: Converted '%s' to '%s'", safeFn, safeNewFn );
538 gtk_dialog_run (GTK_DIALOG (w));
539 gtk_widget_destroy (w);
540 g_free(safeNewFn);
541 g_free(safeFn);
542 }
544 g_free( fn );
545 fn = newFileName;
546 newFileName = 0;
547 }
548 else
549 if ( 0 )
550 {
551 gchar *safeFn = Inkscape::IO::sanitizeString(fn);
552 GtkWidget *w = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "Error: Unable to convert '%s'", safeFn );
553 gtk_dialog_run (GTK_DIALOG (w));
554 gtk_widget_destroy (w);
555 g_free(safeFn);
556 }
557 newFl = g_slist_append( newFl, fn );
558 }
559 return newFl;
560 }
562 int sp_common_main( int argc, char const **argv, GSList **flDest )
563 {
564 /// \todo fixme: Move these to some centralized location (Lauris)
565 sp_object_type_register("sodipodi:namedview", SP_TYPE_NAMEDVIEW);
566 sp_object_type_register("sodipodi:guide", SP_TYPE_GUIDE);
569 // temporarily switch gettext encoding to locale, so that help messages can be output properly
570 gchar const *charset;
571 g_get_charset(&charset);
573 bind_textdomain_codeset(GETTEXT_PACKAGE, charset);
575 poptContext ctx = poptGetContext(NULL, argc, argv, options, 0);
576 poptSetOtherOptionHelp(ctx, _("[OPTIONS...] [FILE...]\n\nAvailable options:"));
577 g_return_val_if_fail(ctx != NULL, 1);
579 /* Collect own arguments */
580 GSList *fl = sp_process_args(ctx);
581 poptFreeContext(ctx);
583 // now switch gettext back to UTF-8 (for GUI)
584 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
586 // Now let's see if the file list still holds up
587 if ( needToRecodeParams )
588 {
589 fl = fixupFilenameEncoding( fl );
590 }
592 // Check the globals for filename-fixup
593 if ( needToRecodeParams )
594 {
595 fixupSingleFilename( &sp_export_png, &sp_export_png_utf8 );
596 fixupSingleFilename( &sp_export_svg, &sp_export_svg_utf8 );
597 fixupSingleFilename( &sp_global_printer, &sp_global_printer_utf8 );
598 }
599 else
600 {
601 if ( sp_export_png )
602 sp_export_png_utf8 = g_strdup( sp_export_png );
603 if ( sp_export_svg )
604 sp_export_svg_utf8 = g_strdup( sp_export_svg );
605 if ( sp_global_printer )
606 sp_global_printer_utf8 = g_strdup( sp_global_printer );
607 }
609 // Return the list if wanted, else free it up.
610 if ( flDest ) {
611 *flDest = fl;
612 fl = 0;
613 } else {
614 while ( fl ) {
615 g_free( fl->data );
616 fl = g_slist_remove( fl, fl->data );
617 }
618 }
619 return 0;
620 }
622 int
623 sp_main_gui(int argc, char const **argv)
624 {
625 Gtk::Main main_instance (&argc, const_cast<char ***>(&argv));
627 GSList *fl = NULL;
628 int retVal = sp_common_main( argc, argv, &fl );
629 g_return_val_if_fail(retVal == 0, 1);
631 inkscape_gtk_stock_init();
633 /* Set default icon */
634 gchar *filename = (gchar *) g_build_filename (INKSCAPE_APPICONDIR, "inkscape.png", NULL);
635 if (Inkscape::IO::file_test(filename, (GFileTest)(G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK))) {
636 gtk_window_set_default_icon_from_file(filename, NULL);
637 }
638 g_free (filename);
639 filename = 0;
641 gboolean create_new = TRUE;
643 /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
644 inkscape_application_init(argv[0], true);
646 while (fl) {
647 if (sp_file_open((gchar *)fl->data,NULL)) {
648 create_new=FALSE;
649 }
650 fl = g_slist_remove(fl, fl->data);
651 }
652 if (create_new) {
653 sp_file_new_default();
654 }
656 Glib::signal_idle().connect(sigc::ptr_fun(&Inkscape::CmdLineAction::idle));
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 }
740 fl = g_slist_remove(fl, fl->data);
741 }
743 inkscape_unref();
745 return 0;
746 }
748 static void
749 do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gchar *id)
750 {
751 SPObject *o = NULL;
753 if (id) {
754 o = doc->getObjectById(id);
755 if (o) {
756 if (!SP_IS_ITEM (o)) {
757 g_warning("Object with id=\"%s\" is not a visible item. Cannot query dimensions.", id);
758 return;
759 }
760 } else {
761 g_warning("Object with id=\"%s\" is not found. Cannot query dimensions.", id);
762 return;
763 }
764 } else {
765 o = SP_DOCUMENT_ROOT(doc);
766 }
768 if (o) {
769 sp_document_ensure_up_to_date (doc);
770 SPItem *item = ((SPItem *) o);
772 // "true" SVG bbox for scripting
773 NR::Maybe<NR::Rect> area = item->getBounds(sp_item_i2doc_affine(item));
774 if (area) {
775 Inkscape::SVGOStringStream os;
776 if (extent) {
777 os << area->extent(axis);
778 } else {
779 os << area->min()[axis];
780 }
781 g_print ("%s", os.str().c_str());
782 } else {
783 g_print("0");
784 }
785 }
786 }
789 static void
790 sp_do_export_png(SPDocument *doc)
791 {
792 const gchar *filename = NULL;
793 gdouble dpi = 0.0;
795 if (sp_export_use_hints && (!sp_export_id && !sp_export_area_drawing)) {
796 g_warning ("--export-use-hints can only be used with --export-id or --export-area-drawing; ignored.");
797 }
799 GSList *items = NULL;
801 NRRect area;
802 if (sp_export_id || sp_export_area_drawing) {
804 SPObject *o = NULL;
805 SPObject *o_area = NULL;
806 if (sp_export_id && sp_export_area_drawing) {
807 o = doc->getObjectById(sp_export_id);
808 o_area = SP_DOCUMENT_ROOT (doc);
809 } else if (sp_export_id) {
810 o = doc->getObjectById(sp_export_id);
811 o_area = o;
812 } else if (sp_export_area_drawing) {
813 o = SP_DOCUMENT_ROOT (doc);
814 o_area = o;
815 }
817 if (o) {
818 if (!SP_IS_ITEM (o)) {
819 g_warning("Object with id=\"%s\" is not a visible item. Nothing exported.", sp_export_id);
820 return;
821 }
823 items = g_slist_prepend (items, SP_ITEM(o));
825 if (sp_export_id_only) {
826 g_print("Exporting only object with id=\"%s\"; all other objects hidden\n", sp_export_id);
827 }
829 if (sp_export_use_hints) {
831 // retrieve export filename hint
832 const gchar *fn_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-filename");
833 if (fn_hint) {
834 if (sp_export_png) {
835 g_warning ("Using export filename from the command line (--export-png). Filename hint %s is ignored.", fn_hint);
836 filename = sp_export_png;
837 } else {
838 filename = fn_hint;
839 }
840 } else {
841 g_warning ("Export filename hint not found for the object.");
842 filename = sp_export_png;
843 }
845 // retrieve export dpi hints
846 const gchar *dpi_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-xdpi"); // only xdpi, ydpi is always the same now
847 if (dpi_hint) {
848 if (sp_export_dpi || sp_export_width || sp_export_height) {
849 g_warning ("Using bitmap dimensions from the command line (--export-dpi, --export-width, or --export-height). DPI hint %s is ignored.", dpi_hint);
850 } else {
851 dpi = atof(dpi_hint);
852 }
853 } else {
854 g_warning ("Export DPI hint not found for the object.");
855 }
857 }
859 // write object bbox to area
860 sp_document_ensure_up_to_date (doc);
861 sp_item_invoke_bbox((SPItem *) o_area, &area, sp_item_i2r_affine((SPItem *) o_area), TRUE);
862 } else {
863 g_warning("Object with id=\"%s\" was not found in the document. Nothing exported.", sp_export_id);
864 return;
865 }
866 }
868 if (sp_export_area) {
869 /* Try to parse area (given in SVG pixels) */
870 if (!sscanf(sp_export_area, "%lg:%lg:%lg:%lg", &area.x0, &area.y0, &area.x1, &area.y1) == 4) {
871 g_warning("Cannot parse export area '%s'; use 'x0:y0:x1:y1'. Nothing exported.", sp_export_area);
872 return;
873 }
874 if ((area.x0 >= area.x1) || (area.y0 >= area.y1)) {
875 g_warning("Export area '%s' has negative width or height. Nothing exported.", sp_export_area);
876 return;
877 }
878 } else if (sp_export_area_canvas || !(sp_export_id || sp_export_area_drawing)) {
879 /* Export the whole canvas */
880 sp_document_ensure_up_to_date (doc);
881 area.x0 = SP_ROOT(doc->root)->x.computed;
882 area.y0 = SP_ROOT(doc->root)->y.computed;
883 area.x1 = area.x0 + sp_document_width (doc);
884 area.y1 = area.y0 + sp_document_height (doc);
885 }
887 // set filename and dpi from options, if not yet set from the hints
888 if (!filename) {
889 if (!sp_export_png) {
890 g_warning ("No export filename given and no filename hint. Nothing exported.");
891 return;
892 }
893 filename = sp_export_png;
894 }
896 if (sp_export_dpi && dpi == 0.0) {
897 dpi = atof(sp_export_dpi);
898 if ((dpi < 0.1) || (dpi > 10000.0)) {
899 g_warning("DPI value %s out of range [0.1 - 10000.0]. Nothing exported.", sp_export_dpi);
900 return;
901 }
902 g_print("DPI: %g\n", dpi);
903 }
905 if (sp_export_area_snap) {
906 area.x0 = std::floor (area.x0);
907 area.y0 = std::floor (area.y0);
908 area.x1 = std::ceil (area.x1);
909 area.y1 = std::ceil (area.y1);
910 }
912 // default dpi
913 if (dpi == 0.0)
914 dpi = PX_PER_IN;
916 gint width = 0;
917 gint height = 0;
919 if (sp_export_width) {
920 width = atoi(sp_export_width);
921 if ((width < 1) || (width > 65536)) {
922 g_warning("Export width %d out of range (1 - 65536). Nothing exported.", width);
923 return;
924 }
925 dpi = (gdouble) width * PX_PER_IN / (area.x1 - area.x0);
926 }
928 if (sp_export_height) {
929 height = atoi(sp_export_height);
930 if ((height < 1) || (height > 65536)) {
931 g_warning("Export height %d out of range (1 - 65536). Nothing exported.", width);
932 return;
933 }
934 dpi = (gdouble) height * PX_PER_IN / (area.y1 - area.y0);
935 }
937 if (!sp_export_width) {
938 width = (gint) ((area.x1 - area.x0) * dpi / PX_PER_IN + 0.5);
939 }
941 if (!sp_export_height) {
942 height = (gint) ((area.y1 - area.y0) * dpi / PX_PER_IN + 0.5);
943 }
945 guint32 bgcolor = 0x00000000;
946 if (sp_export_background) {
947 // override the page color
948 bgcolor = sp_svg_read_color(sp_export_background, 0xffffff00);
949 bgcolor |= 0xff; // default is no opacity
950 } else {
951 // read from namedview
952 Inkscape::XML::Node *nv = sp_repr_lookup_name (doc->rroot, "sodipodi:namedview");
953 if (nv && nv->attribute("pagecolor"))
954 bgcolor = sp_svg_read_color(nv->attribute("pagecolor"), 0xffffff00);
955 if (nv && nv->attribute("inkscape:pageopacity"))
956 bgcolor |= SP_COLOR_F_TO_U(sp_repr_get_double_attribute (nv, "inkscape:pageopacity", 1.0));
957 }
959 if (sp_export_background_opacity) {
960 // override opacity
961 gfloat value;
962 if (sp_svg_number_read_f (sp_export_background_opacity, &value)) {
963 if (value > 1.0) {
964 value = CLAMP (value, 1.0f, 255.0f);
965 bgcolor &= (guint32) 0xffffff00;
966 bgcolor |= (guint32) floor(value);
967 } else {
968 value = CLAMP (value, 0.0f, 1.0f);
969 bgcolor &= (guint32) 0xffffff00;
970 bgcolor |= SP_COLOR_F_TO_U(value);
971 }
972 }
973 }
975 g_print("Background RRGGBBAA: %08x\n", bgcolor);
977 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);
979 g_print("Bitmap saved as: %s\n", filename);
981 if ((width >= 1) && (height >= 1) && (width < 65536) && (height < 65536)) {
982 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);
983 } else {
984 g_warning("Calculated bitmap dimensions %d %d are out of range (1 - 65535). Nothing exported.", width, height);
985 }
987 g_slist_free (items);
988 }
991 /**
992 * Perform an export of either PS or EPS.
993 *
994 * \param doc Document to export.
995 * \param uri URI to export to.
996 * \param mime MIME type to export as.
997 */
999 static void do_export_ps(SPDocument* doc, gchar const* uri, char const* mime)
1000 {
1001 Inkscape::Extension::DB::OutputList o;
1002 Inkscape::Extension::db.get_output_list(o);
1003 Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
1004 while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
1005 i++;
1006 }
1008 if (i == o.end())
1009 {
1010 g_warning ("Could not find an extension to export this file.");
1011 return;
1012 }
1014 bool old_text_to_path = false;
1015 bool old_font_embedded = false;
1016 bool old_bbox_page = false;
1018 try {
1019 old_text_to_path = (*i)->get_param_bool("textToPath");
1020 (*i)->set_param_bool("textToPath", sp_export_text_to_path);
1021 }
1022 catch (...) {
1023 g_warning ("Could not set export-text-to-path option for this export.");
1024 }
1026 try {
1027 old_font_embedded = (*i)->get_param_bool("fontEmbedded");
1028 (*i)->set_param_bool("fontEmbedded", sp_export_font);
1029 }
1030 catch (...) {
1031 g_warning ("Could not set export-font option for this export.");
1032 }
1034 try {
1035 old_bbox_page = (*i)->get_param_bool("pageBoundingBox");
1036 (*i)->set_param_bool("pageBoundingBox", sp_export_bbox_page);
1037 }
1038 catch (...) {
1039 g_warning ("Could not set export-bbox-page option for this export.");
1040 }
1042 (*i)->save(doc, uri);
1044 try {
1045 (*i)->set_param_bool("textToPath", old_text_to_path);
1046 (*i)->set_param_bool("fontEmbedded", old_font_embedded);
1047 (*i)->set_param_bool("pageBoundingBox", old_bbox_page);
1048 }
1049 catch (...) {
1051 }
1052 }
1054 /**
1055 * Perform a PDF export
1056 *
1057 * \param doc Document to export.
1058 * \param uri URI to export to.
1059 * \param mime MIME type to export as.
1060 */
1062 static void do_export_pdf(SPDocument* doc, gchar const* uri, char const* mime)
1063 {
1064 Inkscape::Extension::DB::OutputList o;
1065 Inkscape::Extension::db.get_output_list(o);
1066 Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
1067 while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
1068 i++;
1069 }
1071 if (i == o.end())
1072 {
1073 g_warning ("Could not find an extension to export this file.");
1074 return;
1075 }
1077 (*i)->save(doc, uri);
1078 }
1080 #ifdef WIN32
1081 bool replaceArgs( int& argc, char**& argv )
1082 {
1083 bool worked = false;
1085 #ifdef REPLACEARGS_DEBUG
1086 MessageBoxA( NULL, "GetCommandLineW() getting called", "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1087 #endif // REPLACEARGS_DEBUG
1089 wchar_t* line = GetCommandLineW();
1090 if ( line )
1091 {
1092 #ifdef REPLACEARGS_DEBUG
1093 {
1094 gchar* utf8Line = g_utf16_to_utf8( (gunichar2*)line, -1, NULL, NULL, NULL );
1095 if ( utf8Line )
1096 {
1097 gchar *safe = Inkscape::IO::sanitizeString(utf8Line);
1098 {
1099 char tmp[strlen(safe) + 32];
1100 snprintf( tmp, sizeof(tmp), "GetCommandLineW() = '%s'", safe );
1101 MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1102 }
1103 }
1104 }
1105 #endif // REPLACEARGS_DEBUG
1107 int numArgs = 0;
1108 wchar_t** parsed = CommandLineToArgvW( line, &numArgs );
1110 #ifdef REPLACEARGS_ANSI
1111 // test code for trying things on Win95/98/ME
1112 if ( !parsed )
1113 {
1114 #ifdef REPLACEARGS_DEBUG
1115 MessageBoxA( NULL, "Unable to process command-line. Faking it", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1116 #endif // REPLACEARGS_DEBUG
1117 int lineLen = wcslen(line) + 1;
1118 wchar_t* lineDup = new wchar_t[lineLen];
1119 wcsncpy( lineDup, line, lineLen );
1121 int pos = 0;
1122 bool inQuotes = false;
1123 bool inWhitespace = true;
1124 std::vector<int> places;
1125 while ( lineDup[pos] )
1126 {
1127 if ( inQuotes )
1128 {
1129 if ( lineDup[pos] == L'"' )
1130 {
1131 inQuotes = false;
1132 }
1133 }
1134 else if ( lineDup[pos] == L'"' )
1135 {
1136 inQuotes = true;
1137 inWhitespace = false;
1138 places.push_back(pos);
1139 }
1140 else if ( lineDup[pos] == L' ' || lineDup[pos] == L'\t' )
1141 {
1142 if ( !inWhitespace )
1143 {
1144 inWhitespace = true;
1145 lineDup[pos] = 0;
1146 }
1147 }
1148 else if ( inWhitespace && (lineDup[pos] != L' ' && lineDup[pos] != L'\t') )
1149 {
1150 inWhitespace = false;
1151 places.push_back(pos);
1152 }
1153 else
1154 {
1155 // consume
1156 }
1157 pos++;
1158 }
1159 #ifdef REPLACEARGS_DEBUG
1160 {
1161 char tmp[256];
1162 snprintf( tmp, sizeof(tmp), "Counted %d args", places.size() );
1163 MessageBoxA( NULL, tmp, "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1164 }
1165 #endif // REPLACEARGS_DEBUG
1167 wchar_t** block = new wchar_t*[places.size()];
1168 int i = 0;
1169 for ( std::vector<int>::iterator it = places.begin(); it != places.end(); it++ )
1170 {
1171 block[i++] = &lineDup[*it];
1172 }
1173 parsed = block;
1174 numArgs = places.size();
1175 }
1176 #endif // REPLACEARGS_ANSI
1178 if ( parsed )
1179 {
1180 std::vector<wchar_t*>expandedArgs;
1181 if ( numArgs > 0 )
1182 {
1183 expandedArgs.push_back( parsed[0] );
1184 }
1186 for ( int i1 = 1; i1 < numArgs; i1++ )
1187 {
1188 bool wildcarded = (wcschr(parsed[i1], L'?') != NULL) || (wcschr(parsed[i1], L'*') != NULL);
1189 wildcarded &= parsed[i1][0] != L'"';
1190 wildcarded &= parsed[i1][0] != L'-';
1191 if ( wildcarded )
1192 {
1193 #ifdef REPLACEARGS_ANSI
1194 WIN32_FIND_DATAA data = {0};
1195 #else
1196 WIN32_FIND_DATAW data = {0};
1197 #endif // REPLACEARGS_ANSI
1199 int baseLen = wcslen(parsed[i1]) + 2;
1200 wchar_t* base = new wchar_t[baseLen];
1201 wcsncpy( base, parsed[i1], baseLen );
1202 wchar_t* last = wcsrchr( base, L'\\' );
1203 if ( last )
1204 {
1205 last[1] = 0;
1206 }
1207 else
1208 {
1209 base[0] = 0;
1210 }
1211 baseLen = wcslen( base );
1213 #ifdef REPLACEARGS_ANSI
1214 char target[MAX_PATH];
1215 if ( WideCharToMultiByte( CP_ACP, 0, parsed[i1], -1, target, sizeof(target), NULL, NULL) )
1216 {
1217 HANDLE hf = FindFirstFileA( target, &data );
1218 #else
1219 HANDLE hf = FindFirstFileW( parsed[i1], &data );
1220 #endif // REPLACEARGS_ANSI
1221 if ( hf != INVALID_HANDLE_VALUE )
1222 {
1223 BOOL found = TRUE;
1224 do
1225 {
1226 #ifdef REPLACEARGS_ANSI
1227 int howMany = MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, NULL, 0 );
1228 if ( howMany > 0 )
1229 {
1230 howMany += baseLen;
1231 wchar_t* tmp = new wchar_t[howMany + 1];
1232 wcsncpy( tmp, base, howMany + 1 );
1233 MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, tmp + baseLen, howMany + 1 - baseLen );
1234 expandedArgs.push_back( tmp );
1235 found = FindNextFileA( hf, &data );
1236 }
1237 #else
1238 int howMany = wcslen(data.cFileName) + baseLen;
1239 wchar_t* tmp = new wchar_t[howMany + 1];
1240 wcsncpy( tmp, base, howMany + 1 );
1241 wcsncat( tmp, data.cFileName, howMany + 1 );
1242 expandedArgs.push_back( tmp );
1243 found = FindNextFileW( hf, &data );
1244 #endif // REPLACEARGS_ANSI
1245 } while ( found );
1247 FindClose( hf );
1248 }
1249 else
1250 {
1251 expandedArgs.push_back( parsed[i1] );
1252 }
1253 #ifdef REPLACEARGS_ANSI
1254 }
1255 #endif // REPLACEARGS_ANSI
1257 delete[] base;
1258 }
1259 else
1260 {
1261 expandedArgs.push_back( parsed[i1] );
1262 }
1263 }
1265 {
1266 wchar_t** block = new wchar_t*[expandedArgs.size()];
1267 int iz = 0;
1268 for ( std::vector<wchar_t*>::iterator it = expandedArgs.begin(); it != expandedArgs.end(); it++ )
1269 {
1270 block[iz++] = *it;
1271 }
1272 parsed = block;
1273 numArgs = expandedArgs.size();
1274 }
1276 std::vector<gchar*> newArgs;
1277 for ( int i = 0; i < numArgs; i++ )
1278 {
1279 gchar* replacement = g_utf16_to_utf8( (gunichar2*)parsed[i], -1, NULL, NULL, NULL );
1280 if ( replacement )
1281 {
1282 #ifdef REPLACEARGS_DEBUG
1283 gchar *safe2 = Inkscape::IO::sanitizeString(replacement);
1285 if ( safe2 )
1286 {
1287 {
1288 char tmp[1024];
1289 snprintf( tmp, sizeof(tmp), " [%2d] = '%s'", i, safe2 );
1290 MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1291 }
1292 g_free( safe2 );
1293 }
1294 #endif // REPLACEARGS_DEBUG
1296 newArgs.push_back( replacement );
1297 }
1298 else
1299 {
1300 newArgs.push_back( blankParam );
1301 }
1302 }
1304 // Now push our munged params to be the new argv and argc
1305 {
1306 char** block = new char*[newArgs.size()];
1307 int iz = 0;
1308 for ( std::vector<char*>::iterator it = newArgs.begin(); it != newArgs.end(); it++ )
1309 {
1310 block[iz++] = *it;
1311 }
1312 argv = block;
1313 argc = newArgs.size();
1314 worked = true;
1315 }
1316 }
1317 #ifdef REPLACEARGS_DEBUG
1318 else
1319 {
1320 MessageBoxA( NULL, "Unable to process command-line", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1321 }
1322 #endif // REPLACEARGS_DEBUG
1323 }
1324 #ifdef REPLACEARGS_DEBUG
1325 else
1326 {
1327 {
1328 MessageBoxA( NULL, "Unable to fetch result from GetCommandLineW()", "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1329 }
1331 char* line2 = GetCommandLineA();
1332 if ( line2 )
1333 {
1334 gchar *safe = Inkscape::IO::sanitizeString(line2);
1335 {
1336 {
1337 char tmp[strlen(safe) + 32];
1338 snprintf( tmp, sizeof(tmp), "GetCommandLineA() = '%s'", safe );
1339 MessageBoxA( NULL, tmp, "GetCommandLineA", MB_OK | MB_ICONINFORMATION );
1340 }
1341 }
1342 }
1343 else
1344 {
1345 MessageBoxA( NULL, "Unable to fetch result from GetCommandLineA()", "GetCommandLineA", MB_OK | MB_ICONINFORMATION );
1346 }
1347 }
1348 #endif // REPLACEARGS_DEBUG
1350 return worked;
1351 }
1352 #endif // WIN32
1354 static GSList *
1355 sp_process_args(poptContext ctx)
1356 {
1357 GSList *fl = NULL;
1359 gint a;
1360 while ((a = poptGetNextOpt(ctx)) >= 0) {
1361 switch (a) {
1362 case SP_ARG_FILE: {
1363 gchar const *fn = poptGetOptArg(ctx);
1364 if (fn != NULL) {
1365 fl = g_slist_append(fl, g_strdup(fn));
1366 }
1367 break;
1368 }
1369 case SP_ARG_VERSION: {
1370 printf("Inkscape %s (%s)\n", INKSCAPE_VERSION, __DATE__);
1371 exit(0);
1372 break;
1373 }
1374 case SP_ARG_EXTENSIONDIR: {
1375 printf("%s\n", INKSCAPE_EXTENSIONDIR);
1376 exit(0);
1377 break;
1378 }
1379 case SP_ARG_VERB_LIST: {
1380 // This really shouldn't go here, we should init the app.
1381 // But, since we're just exiting in this path, there is
1382 // no harm, and this is really a better place to put
1383 // everything else.
1384 Inkscape::Extension::init();
1385 Inkscape::Verb::list();
1386 exit(0);
1387 break;
1388 }
1389 case SP_ARG_VERB:
1390 case SP_ARG_SELECT: {
1391 gchar const *arg = poptGetOptArg(ctx);
1392 if (arg != NULL) {
1393 // printf("Adding in: %s\n", arg);
1394 new Inkscape::CmdLineAction((a == SP_ARG_VERB), arg);
1395 }
1396 break;
1397 }
1398 default: {
1399 break;
1400 }
1401 }
1402 }
1404 gchar const ** const args = poptGetArgs(ctx);
1405 if (args != NULL) {
1406 for (unsigned i = 0; args[i] != NULL; i++) {
1407 fl = g_slist_append(fl, g_strdup(args[i]));
1408 }
1409 }
1411 return fl;
1412 }
1415 /*
1416 Local Variables:
1417 mode:c++
1418 c-file-style:"stroustrup"
1419 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
1420 indent-tabs-mode:nil
1421 fill-column:99
1422 End:
1423 */
1424 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :