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