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