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 "helper/png-write.h"
86 #include <extension/extension.h>
87 #include <extension/system.h>
88 #include <extension/db.h>
89 #include <extension/output.h>
91 #ifdef WIN32
92 //#define REPLACEARGS_ANSI
93 //#define REPLACEARGS_DEBUG
95 #include "registrytool.h"
97 #include "extension/internal/win32.h"
98 using Inkscape::Extension::Internal::PrintWin32;
100 #endif // WIN32
102 #include "extension/init.h"
104 #include <glibmm/i18n.h>
105 #include <gtkmm/main.h>
107 #ifndef HAVE_BIND_TEXTDOMAIN_CODESET
108 #define bind_textdomain_codeset(p,c)
109 #endif
111 #include "application/application.h"
113 enum {
114 SP_ARG_NONE,
115 SP_ARG_NOGUI,
116 SP_ARG_GUI,
117 SP_ARG_FILE,
118 SP_ARG_PRINT,
119 SP_ARG_EXPORT_PNG,
120 SP_ARG_EXPORT_DPI,
121 SP_ARG_EXPORT_AREA,
122 SP_ARG_EXPORT_AREA_DRAWING,
123 SP_ARG_EXPORT_AREA_CANVAS,
124 SP_ARG_EXPORT_AREA_SNAP,
125 SP_ARG_EXPORT_WIDTH,
126 SP_ARG_EXPORT_HEIGHT,
127 SP_ARG_EXPORT_ID,
128 SP_ARG_EXPORT_ID_ONLY,
129 SP_ARG_EXPORT_USE_HINTS,
130 SP_ARG_EXPORT_BACKGROUND,
131 SP_ARG_EXPORT_BACKGROUND_OPACITY,
132 SP_ARG_EXPORT_SVG,
133 SP_ARG_EXPORT_PS,
134 SP_ARG_EXPORT_EPS,
135 SP_ARG_EXPORT_PDF,
136 SP_ARG_EXPORT_TEXT_TO_PATH,
137 SP_ARG_EXPORT_BBOX_PAGE,
138 SP_ARG_EXTENSIONDIR,
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_bbox_page = FALSE;
179 static gboolean sp_query_x = FALSE;
180 static gboolean sp_query_y = FALSE;
181 static gboolean sp_query_width = FALSE;
182 static gboolean sp_query_height = FALSE;
183 static gchar *sp_query_id = NULL;
184 static int sp_new_gui = FALSE;
185 static gboolean sp_vacuum_defs = FALSE;
187 static gchar *sp_export_png_utf8 = NULL;
188 static gchar *sp_export_svg_utf8 = NULL;
189 static gchar *sp_global_printer_utf8 = NULL;
191 #ifdef WIN32
192 static bool replaceArgs( int& argc, char**& argv );
193 #endif
194 static GSList *sp_process_args(poptContext ctx);
195 struct poptOption options[] = {
196 {"version", 'V',
197 POPT_ARG_NONE, NULL, SP_ARG_VERSION,
198 N_("Print the Inkscape version number"),
199 NULL},
201 {"without-gui", 'z',
202 POPT_ARG_NONE, NULL, SP_ARG_NOGUI,
203 N_("Do not use X server (only process files from console)"),
204 NULL},
206 {"with-gui", 'g',
207 POPT_ARG_NONE, NULL, SP_ARG_GUI,
208 N_("Try to use X server (even if $DISPLAY is not set)"),
209 NULL},
211 {"file", 'f',
212 POPT_ARG_STRING, NULL, SP_ARG_FILE,
213 N_("Open specified document(s) (option string may be excluded)"),
214 N_("FILENAME")},
216 {"print", 'p',
217 POPT_ARG_STRING, &sp_global_printer, SP_ARG_PRINT,
218 N_("Print document(s) to specified output file (use '| program' for pipe)"),
219 N_("FILENAME")},
221 {"export-png", 'e',
222 POPT_ARG_STRING, &sp_export_png, SP_ARG_EXPORT_PNG,
223 N_("Export document to a PNG file"),
224 N_("FILENAME")},
226 {"export-dpi", 'd',
227 POPT_ARG_STRING, &sp_export_dpi, SP_ARG_EXPORT_DPI,
228 N_("The resolution used for exporting SVG into bitmap (default 90)"),
229 N_("DPI")},
231 {"export-area", 'a',
232 POPT_ARG_STRING, &sp_export_area, SP_ARG_EXPORT_AREA,
233 N_("Exported area in SVG user units (default is the canvas; 0,0 is lower-left corner)"),
234 N_("x0:y0:x1:y1")},
236 {"export-area-drawing", 'D',
237 POPT_ARG_NONE, &sp_export_area_drawing, SP_ARG_EXPORT_AREA_DRAWING,
238 N_("Exported area is the entire drawing (not canvas)"),
239 NULL},
241 {"export-area-canvas", 'C',
242 POPT_ARG_NONE, &sp_export_area_canvas, SP_ARG_EXPORT_AREA_CANVAS,
243 N_("Exported area is the entire canvas"),
244 NULL},
246 {"export-area-snap", 0,
247 POPT_ARG_NONE, &sp_export_area_snap, SP_ARG_EXPORT_AREA_SNAP,
248 N_("Snap the bitmap export area outwards to the nearest integer values (in SVG user units)"),
249 NULL},
251 {"export-width", 'w',
252 POPT_ARG_STRING, &sp_export_width, SP_ARG_EXPORT_WIDTH,
253 N_("The width of exported bitmap in pixels (overrides export-dpi)"),
254 N_("WIDTH")},
256 {"export-height", 'h',
257 POPT_ARG_STRING, &sp_export_height, SP_ARG_EXPORT_HEIGHT,
258 N_("The height of exported bitmap in pixels (overrides export-dpi)"),
259 N_("HEIGHT")},
261 {"export-id", 'i',
262 POPT_ARG_STRING, &sp_export_id, SP_ARG_EXPORT_ID,
263 N_("The ID of the object to export"),
264 N_("ID")},
266 {"export-id-only", 'j',
267 POPT_ARG_NONE, &sp_export_id_only, SP_ARG_EXPORT_ID_ONLY,
268 // TRANSLATORS: this means: "Only export the object whose id is given in --export-id".
269 // See "man inkscape" for details.
270 N_("Export just the object with export-id, hide all others (only with export-id)"),
271 NULL},
273 {"export-use-hints", 't',
274 POPT_ARG_NONE, &sp_export_use_hints, SP_ARG_EXPORT_USE_HINTS,
275 N_("Use stored filename and DPI hints when exporting (only with export-id)"),
276 NULL},
278 {"export-background", 'b',
279 POPT_ARG_STRING, &sp_export_background, SP_ARG_EXPORT_BACKGROUND,
280 N_("Background color of exported bitmap (any SVG-supported color string)"),
281 N_("COLOR")},
283 {"export-background-opacity", 'y',
284 POPT_ARG_STRING, &sp_export_background_opacity, SP_ARG_EXPORT_BACKGROUND_OPACITY,
285 N_("Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)"),
286 N_("VALUE")},
288 {"export-plain-svg", 'l',
289 POPT_ARG_STRING, &sp_export_svg, SP_ARG_EXPORT_SVG,
290 N_("Export document to plain SVG file (no sodipodi or inkscape namespaces)"),
291 N_("FILENAME")},
293 {"export-ps", 'P',
294 POPT_ARG_STRING, &sp_export_ps, SP_ARG_EXPORT_PS,
295 N_("Export document to a PS file"),
296 N_("FILENAME")},
298 {"export-eps", 'E',
299 POPT_ARG_STRING, &sp_export_eps, SP_ARG_EXPORT_EPS,
300 N_("Export document to an EPS file"),
301 N_("FILENAME")},
303 {"export-pdf", 'A',
304 POPT_ARG_STRING, &sp_export_pdf, SP_ARG_EXPORT_PDF,
305 N_("Export document to a PDF file"),
306 N_("FILENAME")},
308 {"export-text-to-path", 'T',
309 POPT_ARG_NONE, &sp_export_text_to_path, SP_ARG_EXPORT_TEXT_TO_PATH,
310 N_("Convert text object to paths on export (EPS)"),
311 NULL},
313 {"export-bbox-page", 'B',
314 POPT_ARG_NONE, &sp_export_bbox_page, SP_ARG_EXPORT_BBOX_PAGE,
315 N_("Export files with the bounding box set to the page size (EPS)"),
316 NULL},
318 {"query-x", 'X',
319 POPT_ARG_NONE, &sp_query_x, SP_ARG_QUERY_X,
320 // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
321 N_("Query the X coordinate of the drawing or, if specified, of the object with --query-id"),
322 NULL},
324 {"query-y", 'Y',
325 POPT_ARG_NONE, &sp_query_y, SP_ARG_QUERY_Y,
326 // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
327 N_("Query the Y coordinate of the drawing or, if specified, of the object with --query-id"),
328 NULL},
330 {"query-width", 'W',
331 POPT_ARG_NONE, &sp_query_width, SP_ARG_QUERY_WIDTH,
332 // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
333 N_("Query the width of the drawing or, if specified, of the object with --query-id"),
334 NULL},
336 {"query-height", 'H',
337 POPT_ARG_NONE, &sp_query_height, SP_ARG_QUERY_HEIGHT,
338 // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help"
339 N_("Query the height of the drawing or, if specified, of the object with --query-id"),
340 NULL},
342 {"query-id", 'I',
343 POPT_ARG_STRING, &sp_query_id, SP_ARG_QUERY_ID,
344 N_("The ID of the object whose dimensions are queried"),
345 N_("ID")},
347 {"extension-directory", 'x',
348 POPT_ARG_NONE, NULL, SP_ARG_EXTENSIONDIR,
349 // TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory
350 N_("Print out the extension directory and exit"),
351 NULL},
353 {"slideshow", 's',
354 POPT_ARG_NONE, &sp_global_slideshow, SP_ARG_SLIDESHOW,
355 N_("Show given files one-by-one, switch to next on any key/mouse event"),
356 NULL},
358 {"vacuum-defs", 0,
359 POPT_ARG_NONE, &sp_vacuum_defs, SP_ARG_VACUUM_DEFS,
360 N_("Remove unused definitions from the defs section(s) of the document"),
361 NULL},
363 POPT_AUTOHELP POPT_TABLEEND
364 };
366 static bool needToRecodeParams = true;
367 gchar* blankParam = "";
369 int
370 main(int argc, char **argv)
371 {
372 #ifdef HAVE_FPSETMASK
373 /* This is inherited from Sodipodi code, where it was in #ifdef __FreeBSD__. It's probably
374 safe to remove: the default mask is already 0 in C99, and in current FreeBSD according to
375 the fenv man page on www.freebsd.org, and in glibc according to (libc)FP Exceptions. */
376 fpsetmask(fpgetmask() & ~(FP_X_DZ | FP_X_INV));
377 #endif
379 #ifdef ENABLE_NLS
380 #ifdef WIN32
381 RegistryTool rt;
382 rt.setPathInfo();
383 gchar *pathBuf = g_strconcat(g_path_get_dirname(argv[0]), "\\", PACKAGE_LOCALE_DIR, NULL);
384 bindtextdomain(GETTEXT_PACKAGE, pathBuf);
385 g_free(pathBuf);
386 #else
387 #ifdef ENABLE_BINRELOC
388 bindtextdomain(GETTEXT_PACKAGE, BR_LOCALEDIR(""));
389 #else
390 bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
391 #endif
392 #endif
393 #endif
395 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
397 #ifdef ENABLE_NLS
398 textdomain(GETTEXT_PACKAGE);
399 #endif
401 LIBXML_TEST_VERSION
403 Inkscape::GC::init();
405 Inkscape::Debug::Logger::init();
407 gboolean use_gui;
408 #ifndef WIN32
409 use_gui = (getenv("DISPLAY") != NULL);
410 #else
411 /*
412 Set the current directory to the directory of the
413 executable. This seems redundant, but is needed for
414 when inkscape.exe is executed from another directory.
415 We use relative paths on win32.
416 HKCR\svgfile\shell\open\command is a good example
417 */
418 /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
419 char *homedir = g_path_get_dirname(argv[0]);
420 SetCurrentDirectory(homedir);
421 g_free(homedir);
423 use_gui = TRUE;
424 #endif
425 /* Test whether with/without GUI is forced */
426 for (int i = 1; i < argc; i++) {
427 if (!strcmp(argv[i], "-z")
428 || !strcmp(argv[i], "--without-gui")
429 || !strcmp(argv[i], "-p")
430 || !strncmp(argv[i], "--print", 7)
431 || !strcmp(argv[i], "-e")
432 || !strncmp(argv[i], "--export-png", 12)
433 || !strcmp(argv[i], "-l")
434 || !strncmp(argv[i], "--export-plain-svg", 12)
435 || !strcmp(argv[i], "-i")
436 || !strncmp(argv[i], "--export-area-drawing", 21)
437 || !strcmp(argv[i], "-D")
438 || !strncmp(argv[i], "--export-area-canvas", 20)
439 || !strcmp(argv[i], "-C")
440 || !strncmp(argv[i], "--export-id", 12)
441 || !strcmp(argv[i], "-P")
442 || !strncmp(argv[i], "--export-ps", 11)
443 || !strcmp(argv[i], "-E")
444 || !strncmp(argv[i], "--export-eps", 12)
445 || !strcmp(argv[i], "-A")
446 || !strncmp(argv[i], "--export-pdf", 12)
447 || !strcmp(argv[i], "-W")
448 || !strncmp(argv[i], "--query-width", 13)
449 || !strcmp(argv[i], "-H")
450 || !strncmp(argv[i], "--query-height", 14)
451 || !strcmp(argv[i], "-X")
452 || !strncmp(argv[i], "--query-x", 13)
453 || !strcmp(argv[i], "-Y")
454 || !strncmp(argv[i], "--query-y", 14)
455 || !strcmp(argv[i], "--vacuum-defs")
456 )
457 {
458 /* main_console handles any exports -- not the gui */
459 use_gui = FALSE;
460 break;
461 } else if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--with-gui")) {
462 use_gui = TRUE;
463 break;
464 }
465 }
467 #ifdef WIN32
468 #ifndef REPLACEARGS_ANSI
469 if ( PrintWin32::is_os_wide() )
470 #endif // REPLACEARGS_ANSI
471 {
472 // If the call fails, we'll need to convert charsets
473 needToRecodeParams = !replaceArgs( argc, argv );
474 }
475 #endif // WIN32
477 /// \todo Should this be a static object (see inkscape.cpp)?
478 Inkscape::NSApplication::Application app(argc, argv, use_gui, sp_new_gui);
480 return app.run();
481 }
483 void fixupSingleFilename( gchar **orig, gchar **spare )
484 {
485 if ( orig && *orig && **orig ) {
486 GError *error = NULL;
487 gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(*orig, -1, NULL, NULL, &error);
488 if ( newFileName )
489 {
490 *orig = newFileName;
491 if ( spare ) {
492 *spare = newFileName;
493 }
494 // g_message("Set a replacement fixup");
495 }
496 }
497 }
499 GSList *fixupFilenameEncoding( GSList* fl )
500 {
501 GSList *newFl = NULL;
502 while ( fl ) {
503 gchar *fn = static_cast<gchar*>(fl->data);
504 fl = g_slist_remove( fl, fl->data );
505 gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(fn, -1, NULL, NULL, NULL);
506 if ( newFileName ) {
508 if ( 0 )
509 {
510 gchar *safeFn = Inkscape::IO::sanitizeString(fn);
511 gchar *safeNewFn = Inkscape::IO::sanitizeString(newFileName);
512 GtkWidget *w = gtk_message_dialog_new( NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
513 "Note: Converted '%s' to '%s'", safeFn, safeNewFn );
514 gtk_dialog_run (GTK_DIALOG (w));
515 gtk_widget_destroy (w);
516 g_free(safeNewFn);
517 g_free(safeFn);
518 }
520 g_free( fn );
521 fn = newFileName;
522 newFileName = 0;
523 }
524 else
525 if ( 0 )
526 {
527 gchar *safeFn = Inkscape::IO::sanitizeString(fn);
528 GtkWidget *w = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "Error: Unable to convert '%s'", safeFn );
529 gtk_dialog_run (GTK_DIALOG (w));
530 gtk_widget_destroy (w);
531 g_free(safeFn);
532 }
533 newFl = g_slist_append( newFl, fn );
534 }
535 return newFl;
536 }
538 int sp_common_main( int argc, char const **argv, GSList **flDest )
539 {
540 /// \todo fixme: Move these to some centralized location (Lauris)
541 sp_object_type_register("sodipodi:namedview", SP_TYPE_NAMEDVIEW);
542 sp_object_type_register("sodipodi:guide", SP_TYPE_GUIDE);
545 // temporarily switch gettext encoding to locale, so that help messages can be output properly
546 gchar const *charset;
547 g_get_charset(&charset);
549 bind_textdomain_codeset(GETTEXT_PACKAGE, charset);
551 poptContext ctx = poptGetContext(NULL, argc, argv, options, 0);
552 poptSetOtherOptionHelp(ctx, _("[OPTIONS...] [FILE...]\n\nAvailable options:"));
553 g_return_val_if_fail(ctx != NULL, 1);
555 /* Collect own arguments */
556 GSList *fl = sp_process_args(ctx);
557 poptFreeContext(ctx);
559 // now switch gettext back to UTF-8 (for GUI)
560 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
562 // Now let's see if the file list still holds up
563 if ( needToRecodeParams )
564 {
565 fl = fixupFilenameEncoding( fl );
566 }
568 // Check the globals for filename-fixup
569 if ( needToRecodeParams )
570 {
571 fixupSingleFilename( &sp_export_png, &sp_export_png_utf8 );
572 fixupSingleFilename( &sp_export_svg, &sp_export_svg_utf8 );
573 fixupSingleFilename( &sp_global_printer, &sp_global_printer_utf8 );
574 }
575 else
576 {
577 if ( sp_export_png )
578 sp_export_png_utf8 = g_strdup( sp_export_png );
579 if ( sp_export_svg )
580 sp_export_svg_utf8 = g_strdup( sp_export_svg );
581 if ( sp_global_printer )
582 sp_global_printer_utf8 = g_strdup( sp_global_printer );
583 }
585 // Return the list if wanted, else free it up.
586 if ( flDest ) {
587 *flDest = fl;
588 fl = 0;
589 } else {
590 while ( fl ) {
591 g_free( fl->data );
592 fl = g_slist_remove( fl, fl->data );
593 }
594 }
595 return 0;
596 }
598 int
599 sp_main_gui(int argc, char const **argv)
600 {
601 Gtk::Main main_instance (&argc, const_cast<char ***>(&argv));
603 GSList *fl = NULL;
604 int retVal = sp_common_main( argc, argv, &fl );
605 g_return_val_if_fail(retVal == 0, 1);
607 inkscape_gtk_stock_init();
609 /* Set default icon */
610 gchar *filename = (gchar *) g_build_filename (INKSCAPE_APPICONDIR, "inkscape.png", NULL);
611 if (Inkscape::IO::file_test(filename, (GFileTest)(G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK))) {
612 gtk_window_set_default_icon_from_file(filename, NULL);
613 }
614 g_free (filename);
615 filename = 0;
617 if (!sp_global_slideshow) {
618 gboolean create_new = TRUE;
620 /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
621 inkscape_application_init(argv[0], true);
623 while (fl) {
624 if (sp_file_open((gchar *)fl->data,NULL)) {
625 create_new=FALSE;
626 }
627 fl = g_slist_remove(fl, fl->data);
628 }
629 if (create_new) {
630 sp_file_new_default();
631 }
632 } else {
633 if (fl) {
634 GtkWidget *ss;
635 /// \todo FIXME BROKEN - non-UTF-8 sneaks in here.
636 inkscape_application_init(argv[0], true);
637 ss = sp_slideshow_new(fl);
638 if (ss) gtk_widget_show(ss);
639 } else {
640 g_warning ("No slides to display");
641 exit(0);
642 }
643 }
645 main_instance.run();
647 #ifdef WIN32
648 //We might not need anything here
649 //sp_win32_finish(); <-- this is a NOP func
650 #endif
652 return 0;
653 }
655 int
656 sp_main_console(int argc, char const **argv)
657 {
658 /* We are started in text mode */
660 /* Do this g_type_init(), so that we can use Xft/Freetype2 (Pango)
661 * in a non-Gtk environment. Used in libnrtype's
662 * FontInstance.cpp and FontFactory.cpp.
663 * http://mail.gnome.org/archives/gtk-list/2003-December/msg00063.html
664 */
665 g_type_init();
666 char **argv2 = const_cast<char **>(argv);
667 gtk_init_check( &argc, &argv2 );
668 //setlocale(LC_ALL, "");
670 GSList *fl = NULL;
671 int retVal = sp_common_main( argc, argv, &fl );
672 g_return_val_if_fail(retVal == 0, 1);
674 if (fl == NULL) {
675 g_print("Nothing to do!\n");
676 exit(0);
677 }
679 inkscape_application_init(argv[0], false);
681 while (fl) {
682 SPDocument *doc;
684 doc = Inkscape::Extension::open(NULL, (gchar *)fl->data);
685 if (doc == NULL) {
686 doc = Inkscape::Extension::open(Inkscape::Extension::db.get(SP_MODULE_KEY_INPUT_SVG), (gchar *)fl->data);
687 }
688 if (doc == NULL) {
689 g_warning("Specified document %s cannot be opened (is it valid SVG file?)", (gchar *) fl->data);
690 } else {
691 if (sp_vacuum_defs) {
692 vacuum_document(doc);
693 }
694 if (sp_vacuum_defs && !sp_export_svg) {
695 // save under the name given in the command line
696 sp_repr_save_file(doc->rdoc, (gchar *)fl->data, SP_SVG_NS_URI);
697 }
698 if (sp_global_printer) {
699 sp_print_document_to_file(doc, sp_global_printer);
700 }
701 if (sp_export_png || sp_export_id || sp_export_area_drawing) {
702 sp_do_export_png(doc);
703 }
704 if (sp_export_svg) {
705 Inkscape::XML::Document *rdoc;
706 Inkscape::XML::Node *repr;
707 rdoc = sp_repr_document_new("svg:svg");
708 repr = rdoc->root();
709 repr = sp_document_root(doc)->updateRepr(repr, SP_OBJECT_WRITE_BUILD);
710 sp_repr_save_file(repr->document(), sp_export_svg, SP_SVG_NS_URI);
711 }
712 if (sp_export_ps) {
713 do_export_ps(doc, sp_export_ps, "image/x-postscript");
714 }
715 if (sp_export_eps) {
716 do_export_ps(doc, sp_export_eps, "image/x-e-postscript");
717 }
718 if (sp_export_pdf) {
719 do_export_pdf(doc, sp_export_pdf, "application/pdf");
720 }
721 if (sp_query_width || sp_query_height) {
722 do_query_dimension (doc, true, sp_query_width? NR::X : NR::Y, sp_query_id);
723 } else if (sp_query_x || sp_query_y) {
724 do_query_dimension (doc, false, sp_query_x? NR::X : NR::Y, sp_query_id);
725 }
726 }
727 fl = g_slist_remove(fl, fl->data);
728 }
730 inkscape_unref();
732 return 0;
733 }
735 static void
736 do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gchar *id)
737 {
738 SPObject *o = NULL;
740 if (id) {
741 o = doc->getObjectById(id);
742 if (o) {
743 if (!SP_IS_ITEM (o)) {
744 g_warning("Object with id=\"%s\" is not a visible item. Cannot query dimensions.", id);
745 return;
746 }
747 } else {
748 g_warning("Object with id=\"%s\" is not found. Cannot query dimensions.", id);
749 return;
750 }
751 } else {
752 o = SP_DOCUMENT_ROOT(doc);
753 }
755 if (o) {
756 sp_document_ensure_up_to_date (doc);
757 SPItem *item = ((SPItem *) o);
758 NR::Rect area = item->invokeBbox(sp_item_i2doc_affine(item)); // "true" SVG bbox for scripting
760 Inkscape::SVGOStringStream os;
761 if (extent) {
762 os << area.extent(axis);
763 } else {
764 os << area.min()[axis];
765 }
766 g_print ("%s", os.str().c_str());
767 }
768 }
771 static void
772 sp_do_export_png(SPDocument *doc)
773 {
774 const gchar *filename = NULL;
775 gdouble dpi = 0.0;
777 if (sp_export_use_hints && (!sp_export_id && !sp_export_area_drawing)) {
778 g_warning ("--export-use-hints can only be used with --export-id or --export-area-drawing; ignored.");
779 }
781 GSList *items = NULL;
783 NRRect area;
784 if (sp_export_id || sp_export_area_drawing) {
786 SPObject *o = NULL;
787 SPObject *o_area = NULL;
788 if (sp_export_id && sp_export_area_drawing) {
789 o = doc->getObjectById(sp_export_id);
790 o_area = SP_DOCUMENT_ROOT (doc);
791 } else if (sp_export_id) {
792 o = doc->getObjectById(sp_export_id);
793 o_area = o;
794 } else if (sp_export_area_drawing) {
795 o = SP_DOCUMENT_ROOT (doc);
796 o_area = o;
797 }
799 if (o) {
800 if (!SP_IS_ITEM (o)) {
801 g_warning("Object with id=\"%s\" is not a visible item. Nothing exported.", sp_export_id);
802 return;
803 }
805 items = g_slist_prepend (items, SP_ITEM(o));
807 if (sp_export_id_only) {
808 g_print("Exporting only object with id=\"%s\"; all other objects hidden\n", sp_export_id);
809 }
811 if (sp_export_use_hints) {
813 // retrieve export filename hint
814 const gchar *fn_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-filename");
815 if (fn_hint) {
816 if (sp_export_png) {
817 g_warning ("Using export filename from the command line (--export-png). Filename hint %s is ignored.", fn_hint);
818 filename = sp_export_png;
819 } else {
820 filename = fn_hint;
821 }
822 } else {
823 g_warning ("Export filename hint not found for the object.");
824 filename = sp_export_png;
825 }
827 // retrieve export dpi hints
828 const gchar *dpi_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-xdpi"); // only xdpi, ydpi is always the same now
829 if (dpi_hint) {
830 if (sp_export_dpi || sp_export_width || sp_export_height) {
831 g_warning ("Using bitmap dimensions from the command line (--export-dpi, --export-width, or --export-height). DPI hint %s is ignored.", dpi_hint);
832 } else {
833 dpi = atof(dpi_hint);
834 }
835 } else {
836 g_warning ("Export DPI hint not found for the object.");
837 }
839 }
841 // write object bbox to area
842 sp_document_ensure_up_to_date (doc);
843 sp_item_invoke_bbox((SPItem *) o_area, &area, sp_item_i2r_affine((SPItem *) o_area), TRUE);
844 } else {
845 g_warning("Object with id=\"%s\" was not found in the document. Nothing exported.", sp_export_id);
846 return;
847 }
848 }
850 if (sp_export_area) {
851 /* Try to parse area (given in SVG pixels) */
852 if (!sscanf(sp_export_area, "%lg:%lg:%lg:%lg", &area.x0, &area.y0, &area.x1, &area.y1) == 4) {
853 g_warning("Cannot parse export area '%s'; use 'x0:y0:x1:y1'. Nothing exported.", sp_export_area);
854 return;
855 }
856 if ((area.x0 >= area.x1) || (area.y0 >= area.y1)) {
857 g_warning("Export area '%s' has negative width or height. Nothing exported.", sp_export_area);
858 return;
859 }
860 } else if (sp_export_area_canvas || !(sp_export_id || sp_export_area_drawing)) {
861 /* Export the whole canvas */
862 sp_document_ensure_up_to_date (doc);
863 area.x0 = SP_ROOT(doc->root)->x.computed;
864 area.y0 = SP_ROOT(doc->root)->y.computed;
865 area.x1 = area.x0 + sp_document_width (doc);
866 area.y1 = area.y0 + sp_document_height (doc);
867 }
869 // set filename and dpi from options, if not yet set from the hints
870 if (!filename) {
871 if (!sp_export_png) {
872 g_warning ("No export filename given and no filename hint. Nothing exported.");
873 return;
874 }
875 filename = sp_export_png;
876 }
878 if (sp_export_dpi && dpi == 0.0) {
879 dpi = atof(sp_export_dpi);
880 if ((dpi < 0.1) || (dpi > 10000.0)) {
881 g_warning("DPI value %s out of range [0.1 - 10000.0]. Nothing exported.", sp_export_dpi);
882 return;
883 }
884 g_print("DPI: %g\n", dpi);
885 }
887 if (sp_export_area_snap) {
888 area.x0 = std::floor (area.x0);
889 area.y0 = std::floor (area.y0);
890 area.x1 = std::ceil (area.x1);
891 area.y1 = std::ceil (area.y1);
892 }
894 // default dpi
895 if (dpi == 0.0)
896 dpi = PX_PER_IN;
898 gint width = 0;
899 gint height = 0;
901 if (sp_export_width) {
902 width = atoi(sp_export_width);
903 if ((width < 1) || (width > 65536)) {
904 g_warning("Export width %d out of range (1 - 65536). Nothing exported.", width);
905 return;
906 }
907 dpi = (gdouble) width * PX_PER_IN / (area.x1 - area.x0);
908 }
910 if (sp_export_height) {
911 height = atoi(sp_export_height);
912 if ((height < 1) || (height > 65536)) {
913 g_warning("Export height %d out of range (1 - 65536). Nothing exported.", width);
914 return;
915 }
916 dpi = (gdouble) height * PX_PER_IN / (area.y1 - area.y0);
917 }
919 if (!sp_export_width) {
920 width = (gint) ((area.x1 - area.x0) * dpi / PX_PER_IN + 0.5);
921 }
923 if (!sp_export_height) {
924 height = (gint) ((area.y1 - area.y0) * dpi / PX_PER_IN + 0.5);
925 }
927 guint32 bgcolor = 0x00000000;
928 if (sp_export_background) {
929 // override the page color
930 bgcolor = sp_svg_read_color(sp_export_background, 0xffffff00);
931 bgcolor |= 0xff; // default is no opacity
932 } else {
933 // read from namedview
934 Inkscape::XML::Node *nv = sp_repr_lookup_name (doc->rroot, "sodipodi:namedview");
935 if (nv && nv->attribute("pagecolor"))
936 bgcolor = sp_svg_read_color(nv->attribute("pagecolor"), 0xffffff00);
937 if (nv && nv->attribute("inkscape:pageopacity"))
938 bgcolor |= SP_COLOR_F_TO_U(sp_repr_get_double_attribute (nv, "inkscape:pageopacity", 1.0));
939 }
941 if (sp_export_background_opacity) {
942 // override opacity
943 gfloat value;
944 if (sp_svg_number_read_f (sp_export_background_opacity, &value)) {
945 if (value > 1.0) {
946 value = CLAMP (value, 1.0f, 255.0f);
947 bgcolor &= (guint32) 0xffffff00;
948 bgcolor |= (guint32) floor(value);
949 } else {
950 value = CLAMP (value, 0.0f, 1.0f);
951 bgcolor &= (guint32) 0xffffff00;
952 bgcolor |= SP_COLOR_F_TO_U(value);
953 }
954 }
955 }
957 g_print("Background RRGGBBAA: %08x\n", bgcolor);
959 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);
961 g_print("Bitmap saved as: %s\n", filename);
963 if ((width >= 1) && (height >= 1) && (width < 65536) && (height < 65536)) {
964 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);
965 } else {
966 g_warning("Calculated bitmap dimensions %d %d are out of range (1 - 65535). Nothing exported.", width, height);
967 }
969 g_slist_free (items);
970 }
973 /**
974 * Perform an export of either PS or EPS.
975 *
976 * \param doc Document to export.
977 * \param uri URI to export to.
978 * \param mime MIME type to export as.
979 */
981 static void do_export_ps(SPDocument* doc, gchar const* uri, char const* mime)
982 {
983 Inkscape::Extension::DB::OutputList o;
984 Inkscape::Extension::db.get_output_list(o);
985 Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
986 while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
987 i++;
988 }
990 if (i == o.end())
991 {
992 g_warning ("Could not find an extension to export this file.");
993 return;
994 }
996 bool old_text_to_path = false;
997 bool old_bbox_page = false;
999 try {
1000 old_text_to_path = (*i)->get_param_bool("textToPath");
1001 (*i)->set_param_bool("textToPath", sp_export_text_to_path);
1002 }
1003 catch (...) {
1004 g_warning ("Could not set export-text-to-path option for this export.");
1005 }
1007 try {
1008 old_bbox_page = (*i)->get_param_bool("pageBoundingBox");
1009 (*i)->set_param_bool("pageBoundingBox", sp_export_bbox_page);
1010 }
1011 catch (...) {
1012 g_warning ("Could not set export-bbox-page option for this export.");
1013 }
1015 (*i)->save(doc, uri);
1017 try {
1018 (*i)->set_param_bool("textToPath", old_text_to_path);
1019 (*i)->set_param_bool("pageBoundingBox", old_bbox_page);
1020 }
1021 catch (...) {
1023 }
1024 }
1026 /**
1027 * Perform a PDF export
1028 *
1029 * \param doc Document to export.
1030 * \param uri URI to export to.
1031 * \param mime MIME type to export as.
1032 */
1034 static void do_export_pdf(SPDocument* doc, gchar const* uri, char const* mime)
1035 {
1036 Inkscape::Extension::DB::OutputList o;
1037 Inkscape::Extension::db.get_output_list(o);
1038 Inkscape::Extension::DB::OutputList::const_iterator i = o.begin();
1039 while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) {
1040 i++;
1041 }
1043 if (i == o.end())
1044 {
1045 g_warning ("Could not find an extension to export this file.");
1046 return;
1047 }
1049 (*i)->save(doc, uri);
1050 }
1052 #ifdef WIN32
1053 bool replaceArgs( int& argc, char**& argv )
1054 {
1055 bool worked = false;
1057 #ifdef REPLACEARGS_DEBUG
1058 MessageBoxA( NULL, "GetCommandLineW() getting called", "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1059 #endif // REPLACEARGS_DEBUG
1061 wchar_t* line = GetCommandLineW();
1062 if ( line )
1063 {
1064 #ifdef REPLACEARGS_DEBUG
1065 {
1066 gchar* utf8Line = g_utf16_to_utf8( (gunichar2*)line, -1, NULL, NULL, NULL );
1067 if ( utf8Line )
1068 {
1069 gchar *safe = Inkscape::IO::sanitizeString(utf8Line);
1070 {
1071 char tmp[strlen(safe) + 32];
1072 snprintf( tmp, sizeof(tmp), "GetCommandLineW() = '%s'", safe );
1073 MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1074 }
1075 }
1076 }
1077 #endif // REPLACEARGS_DEBUG
1079 int numArgs = 0;
1080 wchar_t** parsed = CommandLineToArgvW( line, &numArgs );
1082 #ifdef REPLACEARGS_ANSI
1083 // test code for trying things on Win95/98/ME
1084 if ( !parsed )
1085 {
1086 #ifdef REPLACEARGS_DEBUG
1087 MessageBoxA( NULL, "Unable to process command-line. Faking it", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1088 #endif // REPLACEARGS_DEBUG
1089 int lineLen = wcslen(line) + 1;
1090 wchar_t* lineDup = new wchar_t[lineLen];
1091 wcsncpy( lineDup, line, lineLen );
1093 int pos = 0;
1094 bool inQuotes = false;
1095 bool inWhitespace = true;
1096 std::vector<int> places;
1097 while ( lineDup[pos] )
1098 {
1099 if ( inQuotes )
1100 {
1101 if ( lineDup[pos] == L'"' )
1102 {
1103 inQuotes = false;
1104 }
1105 }
1106 else if ( lineDup[pos] == L'"' )
1107 {
1108 inQuotes = true;
1109 inWhitespace = false;
1110 places.push_back(pos);
1111 }
1112 else if ( lineDup[pos] == L' ' || lineDup[pos] == L'\t' )
1113 {
1114 if ( !inWhitespace )
1115 {
1116 inWhitespace = true;
1117 lineDup[pos] = 0;
1118 }
1119 }
1120 else if ( inWhitespace && (lineDup[pos] != L' ' && lineDup[pos] != L'\t') )
1121 {
1122 inWhitespace = false;
1123 places.push_back(pos);
1124 }
1125 else
1126 {
1127 // consume
1128 }
1129 pos++;
1130 }
1131 #ifdef REPLACEARGS_DEBUG
1132 {
1133 char tmp[256];
1134 snprintf( tmp, sizeof(tmp), "Counted %d args", places.size() );
1135 MessageBoxA( NULL, tmp, "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1136 }
1137 #endif // REPLACEARGS_DEBUG
1139 wchar_t** block = new wchar_t*[places.size()];
1140 int i = 0;
1141 for ( std::vector<int>::iterator it = places.begin(); it != places.end(); it++ )
1142 {
1143 block[i++] = &lineDup[*it];
1144 }
1145 parsed = block;
1146 numArgs = places.size();
1147 }
1148 #endif // REPLACEARGS_ANSI
1150 if ( parsed )
1151 {
1152 std::vector<wchar_t*>expandedArgs;
1153 if ( numArgs > 0 )
1154 {
1155 expandedArgs.push_back( parsed[0] );
1156 }
1158 for ( int i1 = 1; i1 < numArgs; i1++ )
1159 {
1160 bool wildcarded = (wcschr(parsed[i1], L'?') != NULL) || (wcschr(parsed[i1], L'*') != NULL);
1161 wildcarded &= parsed[i1][0] != L'"';
1162 wildcarded &= parsed[i1][0] != L'-';
1163 if ( wildcarded )
1164 {
1165 #ifdef REPLACEARGS_ANSI
1166 WIN32_FIND_DATAA data = {0};
1167 #else
1168 WIN32_FIND_DATAW data = {0};
1169 #endif // REPLACEARGS_ANSI
1171 int baseLen = wcslen(parsed[i1]) + 2;
1172 wchar_t* base = new wchar_t[baseLen];
1173 wcsncpy( base, parsed[i1], baseLen );
1174 wchar_t* last = wcsrchr( base, L'\\' );
1175 if ( last )
1176 {
1177 last[1] = 0;
1178 }
1179 else
1180 {
1181 base[0] = 0;
1182 }
1183 baseLen = wcslen( base );
1185 #ifdef REPLACEARGS_ANSI
1186 char target[MAX_PATH];
1187 if ( WideCharToMultiByte( CP_ACP, 0, parsed[i1], -1, target, sizeof(target), NULL, NULL) )
1188 {
1189 HANDLE hf = FindFirstFileA( target, &data );
1190 #else
1191 HANDLE hf = FindFirstFileW( parsed[i1], &data );
1192 #endif // REPLACEARGS_ANSI
1193 if ( hf != INVALID_HANDLE_VALUE )
1194 {
1195 BOOL found = TRUE;
1196 do
1197 {
1198 #ifdef REPLACEARGS_ANSI
1199 int howMany = MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, NULL, 0 );
1200 if ( howMany > 0 )
1201 {
1202 howMany += baseLen;
1203 wchar_t* tmp = new wchar_t[howMany + 1];
1204 wcsncpy( tmp, base, howMany + 1 );
1205 MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, tmp + baseLen, howMany + 1 - baseLen );
1206 expandedArgs.push_back( tmp );
1207 found = FindNextFileA( hf, &data );
1208 }
1209 #else
1210 int howMany = wcslen(data.cFileName) + baseLen;
1211 wchar_t* tmp = new wchar_t[howMany + 1];
1212 wcsncpy( tmp, base, howMany + 1 );
1213 wcsncat( tmp, data.cFileName, howMany + 1 );
1214 expandedArgs.push_back( tmp );
1215 found = FindNextFileW( hf, &data );
1216 #endif // REPLACEARGS_ANSI
1217 } while ( found );
1219 FindClose( hf );
1220 }
1221 else
1222 {
1223 expandedArgs.push_back( parsed[i1] );
1224 }
1225 #ifdef REPLACEARGS_ANSI
1226 }
1227 #endif // REPLACEARGS_ANSI
1229 delete[] base;
1230 }
1231 else
1232 {
1233 expandedArgs.push_back( parsed[i1] );
1234 }
1235 }
1237 {
1238 wchar_t** block = new wchar_t*[expandedArgs.size()];
1239 int iz = 0;
1240 for ( std::vector<wchar_t*>::iterator it = expandedArgs.begin(); it != expandedArgs.end(); it++ )
1241 {
1242 block[iz++] = *it;
1243 }
1244 parsed = block;
1245 numArgs = expandedArgs.size();
1246 }
1248 std::vector<gchar*> newArgs;
1249 for ( int i = 0; i < numArgs; i++ )
1250 {
1251 gchar* replacement = g_utf16_to_utf8( (gunichar2*)parsed[i], -1, NULL, NULL, NULL );
1252 if ( replacement )
1253 {
1254 #ifdef REPLACEARGS_DEBUG
1255 gchar *safe2 = Inkscape::IO::sanitizeString(replacement);
1257 if ( safe2 )
1258 {
1259 {
1260 char tmp[1024];
1261 snprintf( tmp, sizeof(tmp), " [%2d] = '%s'", i, safe2 );
1262 MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1263 }
1264 g_free( safe2 );
1265 }
1266 #endif // REPLACEARGS_DEBUG
1268 newArgs.push_back( replacement );
1269 }
1270 else
1271 {
1272 newArgs.push_back( blankParam );
1273 }
1274 }
1276 // Now push our munged params to be the new argv and argc
1277 {
1278 char** block = new char*[newArgs.size()];
1279 int iz = 0;
1280 for ( std::vector<char*>::iterator it = newArgs.begin(); it != newArgs.end(); it++ )
1281 {
1282 block[iz++] = *it;
1283 }
1284 argv = block;
1285 argc = newArgs.size();
1286 worked = true;
1287 }
1288 }
1289 #ifdef REPLACEARGS_DEBUG
1290 else
1291 {
1292 MessageBoxA( NULL, "Unable to process command-line", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION );
1293 }
1294 #endif // REPLACEARGS_DEBUG
1295 }
1296 #ifdef REPLACEARGS_DEBUG
1297 else
1298 {
1299 {
1300 MessageBoxA( NULL, "Unable to fetch result from GetCommandLineW()", "GetCommandLineW", MB_OK | MB_ICONINFORMATION );
1301 }
1303 char* line2 = GetCommandLineA();
1304 if ( line2 )
1305 {
1306 gchar *safe = Inkscape::IO::sanitizeString(line2);
1307 {
1308 {
1309 char tmp[strlen(safe) + 32];
1310 snprintf( tmp, sizeof(tmp), "GetCommandLineA() = '%s'", safe );
1311 MessageBoxA( NULL, tmp, "GetCommandLineA", MB_OK | MB_ICONINFORMATION );
1312 }
1313 }
1314 }
1315 else
1316 {
1317 MessageBoxA( NULL, "Unable to fetch result from GetCommandLineA()", "GetCommandLineA", MB_OK | MB_ICONINFORMATION );
1318 }
1319 }
1320 #endif // REPLACEARGS_DEBUG
1322 return worked;
1323 }
1324 #endif // WIN32
1326 static GSList *
1327 sp_process_args(poptContext ctx)
1328 {
1329 GSList *fl = NULL;
1331 gint a;
1332 while ((a = poptGetNextOpt(ctx)) >= 0) {
1333 switch (a) {
1334 case SP_ARG_FILE: {
1335 gchar const *fn = poptGetOptArg(ctx);
1336 if (fn != NULL) {
1337 fl = g_slist_append(fl, g_strdup(fn));
1338 }
1339 break;
1340 }
1341 case SP_ARG_VERSION: {
1342 printf("Inkscape %s (%s)\n", INKSCAPE_VERSION, __DATE__);
1343 exit(0);
1344 break;
1345 }
1346 case SP_ARG_EXTENSIONDIR: {
1347 printf("%s\n", INKSCAPE_EXTENSIONDIR);
1348 exit(0);
1349 break;
1350 }
1351 default: {
1352 break;
1353 }
1354 }
1355 }
1357 gchar const ** const args = poptGetArgs(ctx);
1358 if (args != NULL) {
1359 for (unsigned i = 0; args[i] != NULL; i++) {
1360 fl = g_slist_append(fl, g_strdup(args[i]));
1361 }
1362 }
1364 return fl;
1365 }
1368 /*
1369 Local Variables:
1370 mode:c++
1371 c-file-style:"stroustrup"
1372 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
1373 indent-tabs-mode:nil
1374 fill-column:99
1375 End:
1376 */
1377 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :