GDS-Render v1.2.1
main.c
Go to the documentation of this file.
1/*
2 * GDSII-Converter
3 * Copyright (C) 2018 Mario Hüttel <mario.huettel@gmx.net>
4 *
5 * This file is part of GDSII-Converter.
6 *
7 * GDSII-Converter is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * GDSII-Converter is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
18 */
19
26#include <stdio.h>
27#include <gtk/gtk.h>
28#include <glib.h>
29#include <glib/gi18n.h>
30#include <locale.h>
31
35#include <gds-render/version.h>
36
41 GtkApplication *app;
42 GList *gui_list;
43};
44
58static void app_quit(GSimpleAction *action, GVariant *parameter, gpointer user_data)
59{
60 struct application_data * const appdata = (struct application_data *)user_data;
61 (void)action;
62 (void)parameter;
63 GList *list_iter;
64 GdsRenderGui *gui;
65
66 /* Dispose all GUIs */
67 for (list_iter = appdata->gui_list; list_iter != NULL; list_iter = g_list_next(list_iter)) {
68 gui = RENDERER_GUI(list_iter->data);
69 g_object_unref(gui);
70 }
71
72 g_list_free(appdata->gui_list);
73 appdata->gui_list = NULL;
74}
75
85static void app_about(GSimpleAction *action, GVariant *parameter, gpointer user_data)
86{
87 GtkBuilder *builder;
88 GtkDialog *dialog;
89 GdkPixbuf *logo_buf;
90 GError *error = NULL;
91 (void)user_data;
92 (void)action;
93 (void)parameter;
94 GString *comment_text;
95
96 comment_text = g_string_new(_("gds-render is a free tool for rendering GDS2 layout files into vector graphics."));
97 g_string_append_printf(comment_text, _("\n\nFull git commit: %s"), _app_git_commit);
98
99 builder = gtk_builder_new_from_resource("/gui/about.glade");
100 dialog = GTK_DIALOG(gtk_builder_get_object(builder, "about-dialog"));
101 gtk_window_set_transient_for(GTK_WINDOW(dialog), NULL);
102 gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), _app_version_string);
103 gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(dialog), comment_text->str);
104
105 g_string_free(comment_text, TRUE);
106
107 /* Load icon from resource */
108 logo_buf = gdk_pixbuf_new_from_resource_at_scale("/images/logo.svg", 100, 100, TRUE, &error);
109 if (logo_buf) {
110 /* Set logo */
111 gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(dialog), logo_buf);
112
113 /* Pixbuf is now owned by about dialog. Unref */
114 g_object_unref(logo_buf);
115 } else if (error) {
116 fprintf(stderr, _("Logo could not be displayed: %s\n"), error->message);
117 g_error_free(error);
118 }
119
120 gtk_dialog_run(dialog);
121
122 gtk_widget_destroy(GTK_WIDGET(dialog));
123 g_object_unref(builder);
124}
125
129static const GActionEntry app_actions[] = {
130 { "quit", app_quit, NULL, NULL, NULL, {0} },
131 { "about", app_about, NULL, NULL, NULL, {0} },
132};
133
143static void gui_window_closed_callback(GdsRenderGui *gui, gpointer user_data)
144{
145 GList **gui_list = (GList **)user_data;
146
147 /* Dispose of Gui element */
148 *gui_list = g_list_remove(*gui_list, gui);
149 g_object_unref(gui);
150}
151
157static void gapp_activate(GApplication *app, gpointer user_data)
158{
159 GtkWindow *main_window;
160 GdsRenderGui *gui;
161 struct application_data * const appdata = (struct application_data *)user_data;
162
163 gui = gds_render_gui_new();
164 appdata->gui_list = g_list_append(appdata->gui_list, gui);
165
166 g_signal_connect(gui, "window-closed", G_CALLBACK(gui_window_closed_callback), &appdata->gui_list);
167
168 main_window = gds_render_gui_get_main_window(gui);
169
170 gtk_application_add_window(GTK_APPLICATION(app), main_window);
171 gtk_widget_show(GTK_WIDGET(main_window));
172}
173
185static int start_gui(int argc, char **argv)
186{
187 GtkApplication *gapp;
188 GString *application_domain;
189 int app_status;
190 static struct application_data appdata = {
191 .gui_list = NULL
192 };
193 GMenu *menu;
194 GMenu *m_quit;
195 GMenu *m_about;
196
197 /*
198 * Generate version dependent application id
199 * This allows running the application in different versions at the same time.
200 */
201 application_domain = g_string_new(NULL);
202 g_string_printf(application_domain, "de.shimatta.gds_render_%s", _app_git_commit);
203
204 gapp = gtk_application_new(application_domain->str, G_APPLICATION_FLAGS_NONE);
205 g_string_free(application_domain, TRUE);
206
207 g_application_register(G_APPLICATION(gapp), NULL, NULL);
208 g_signal_connect(gapp, "activate", G_CALLBACK(gapp_activate), &appdata);
209
210 if (g_application_get_is_remote(G_APPLICATION(gapp)) == TRUE) {
211 g_application_activate(G_APPLICATION(gapp));
212 printf(_("There is already an open instance. Will open second window in that instance.\n"));
213 return 0;
214 }
215
216 menu = g_menu_new();
217 m_quit = g_menu_new();
218 m_about = g_menu_new();
219 g_menu_append(m_quit, _("Quit"), "app.quit");
220 g_menu_append(m_about, _("About"), "app.about");
221 g_menu_append_section(menu, NULL, G_MENU_MODEL(m_about));
222 g_menu_append_section(menu, NULL, G_MENU_MODEL(m_quit));
223 g_action_map_add_action_entries(G_ACTION_MAP(gapp), app_actions,
224 G_N_ELEMENTS(app_actions), &appdata);
225 gtk_application_set_app_menu(GTK_APPLICATION(gapp), G_MENU_MODEL(menu));
226
227 g_object_unref(m_quit);
228 g_object_unref(m_about);
229 g_object_unref(menu);
230
231 app_status = g_application_run(G_APPLICATION(gapp), argc, argv);
232 g_object_unref(gapp);
233
234 g_list_free(appdata.gui_list);
235
236 return app_status;
237}
238
242static void print_version(void)
243{
244 printf(_("This is gds-render, version: %s\n\nFor a list of supported commands execute with --help option.\n"),
246}
247
254int main(int argc, char **argv)
255{
256 int i;
257 GError *error = NULL;
258 GOptionContext *context;
259 gchar *gds_name;
260 gchar **output_paths = NULL;
261 gchar *mappingname = NULL;
262 gchar *cellname = NULL;
263 gchar **renderer_args = NULL;
264 gboolean version = FALSE, pdf_standalone = FALSE, pdf_layers = FALSE;
265 int scale = 1000;
266 int app_status = 0;
267 struct external_renderer_params so_render_params;
268
269 so_render_params.so_path = NULL;
270 so_render_params.cli_params = NULL;
271
272 bindtextdomain(GETTEXT_PACKAGE, LOCALEDATADIR "/locale");
273 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
274 textdomain(GETTEXT_PACKAGE);
275
276 GOptionEntry entries[] = {
277 {"version", 'v', 0, G_OPTION_ARG_NONE, &version, _("Print version"), NULL},
278 {"renderer", 'r', 0, G_OPTION_ARG_STRING_ARRAY, &renderer_args,
279 _("Renderer to use. Can be used multiple times."), "pdf|svg|tikz|ext"},
280 {"scale", 's', 0, G_OPTION_ARG_INT, &scale, _("Divide output coordinates by <SCALE>"), "<SCALE>" },
281 {"output-file", 'o', 0, G_OPTION_ARG_FILENAME_ARRAY, &output_paths,
282 _("Output file path. Can be used multiple times."), "PATH" },
283 {"mapping", 'm', 0, G_OPTION_ARG_FILENAME, &mappingname, _("Path for Layer Mapping File"), "PATH" },
284 {"cell", 'c', 0, G_OPTION_ARG_STRING, &cellname, _("Cell to render"), "NAME" },
285 {"tex-standalone", 'a', 0, G_OPTION_ARG_NONE, &pdf_standalone, _("Create standalone TeX"), NULL },
286 {"tex-layers", 'l', 0, G_OPTION_ARG_NONE, &pdf_layers, _("Create PDF Layers (OCG)"), NULL },
287 {"custom-render-lib", 'P', 0, G_OPTION_ARG_FILENAME, &so_render_params.so_path,
288 _("Path to a custom shared object, that implements the necessary rendering functions"), "PATH"},
289 {"render-lib-params", 'W', 0, G_OPTION_ARG_STRING, &so_render_params.cli_params,
290 _("Argument string passed to render lib"), NULL},
291 {NULL, 0, 0, 0, NULL, NULL, NULL}
292 };
293
294 context = g_option_context_new(_(" FILE - Convert GDS file <FILE> to graphic"));
295 g_option_context_add_main_entries(context, entries, NULL);
296 g_option_context_add_group(context, gtk_get_option_group(TRUE));
297
298 if (!g_option_context_parse(context, &argc, &argv, &error)) {
299 g_print(_("Option parsing failed: %s\n"), error->message);
300 exit(1);
301 }
302
303 g_option_context_free(context);
304
305 if (version) {
307 goto ret_status;
308 }
309
310 if (argc >= 2) {
311 if (scale < 1) {
312 printf(_("Scale < 1 not allowed. Setting to 1\n"));
313 scale = 1;
314 }
315
316 /* Get gds name */
317 gds_name = argv[1];
318
319 /* Print out additional arguments as ignored */
320 for (i = 2; i < argc; i++)
321 printf(_("Ignored argument: %s"), argv[i]);
322
323 app_status =
324 command_line_convert_gds(gds_name, cellname, renderer_args, output_paths, mappingname,
325 &so_render_params, pdf_standalone, pdf_layers, scale);
326
327 } else {
328 app_status = start_gui(argc, argv);
329 }
330
331ret_status:
332 /* If necessary, free command line parameters.
333 * This is only really necessary for automated mem-leak testing.
334 * Omitting these frees would be perfectly fine.
335 */
336 if (output_paths)
337 g_strfreev(output_paths);
338 if (renderer_args)
339 g_strfreev(renderer_args);
340 if (mappingname)
341 g_free(mappingname);
342 if (cellname)
343 free(cellname);
344 if (so_render_params.so_path)
345 free(so_render_params.so_path);
346 if (so_render_params.cli_params)
347 g_free(so_render_params.cli_params);
348
349 return app_status;
350}
Render according to command line parameters.
Render according to command line parameters.
Header for GdsRenderGui Object.
GtkWindow * gds_render_gui_get_main_window(GdsRenderGui *gui)
Get main window.
GdsRenderGui * gds_render_gui_new()
Create new GdsRenderGui Object.
int command_line_convert_gds(const char *gds_name, const char *cell_name, char **renderers, char **output_file_names, const char *layer_file, struct external_renderer_params *ext_param, gboolean tex_standalone, gboolean tex_layers, double scale)
Convert GDS according to command line parameters.
Definition: command-line.c:138
const char * _app_version_string
This string holds the Git Based Version Number of the app.
Definition: version.c:32
const char * _app_git_commit
This string holds the git commit hash of the current HEAD revision.
Definition: version.c:40
static void print_version(void)
Print the application version string to stdout.
Definition: main.c:242
static const GActionEntry app_actions[]
Contains the application menu entries.
Definition: main.c:129
int main(int argc, char **argv)
The "entry point" of the application.
Definition: main.c:254
static void app_quit(GSimpleAction *action, GVariant *parameter, gpointer user_data)
Callback for the menu entry 'Quit'.
Definition: main.c:58
static void app_about(GSimpleAction *action, GVariant *parameter, gpointer user_data)
Callback for the 'About' menu entry.
Definition: main.c:85
static int start_gui(int argc, char **argv)
Start the graphical interface.
Definition: main.c:185
static void gapp_activate(GApplication *app, gpointer user_data)
Activation of the GUI.
Definition: main.c:157
static void gui_window_closed_callback(GdsRenderGui *gui, gpointer user_data)
Called when a GUI main window is closed.
Definition: main.c:143
Structure containing The GtkApplication and a list containing the GdsRenderGui objects.
Definition: main.c:40
GtkApplication * app
Definition: main.c:41
GList * gui_list
Definition: main.c:42
External renderer paramameters to command line renderer.
Definition: command-line.h:39
char * cli_params
Command line parameters given.
Definition: command-line.h:48
char * so_path
Path to shared object.
Definition: command-line.h:43