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