Graphviz 13.0.0~dev.20250121.0651
Loading...
Searching...
No Matches
main.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#include "builddate.h"
12#include "config.h"
13// windows.h for win machines
14#if defined(_WIN32) && !defined(__CYGWIN__)
15#include <windows.h>
16#include <windowsx.h>
17#endif
18#include "frmobjectui.h"
19#include "gltemplate.h"
20#include "gui.h"
21#include "gvprpipe.h"
22#include "menucallbacks.h"
23#include "support.h"
24#include "viewport.h"
25#include <glade/glade.h>
26#include <gtk/gtk.h>
27#include <gtk/gtkgl.h>
28#ifdef ENABLE_NLS
29#include "libintl.h"
30#endif
31#include "glexpose.h"
32#include "glutrender.h"
33#include <assert.h>
34
35#include <getopt.h>
36#include <stdlib.h>
37#include <string.h>
38#include <util/alloc.h>
39#include <util/exit.h>
40#include <util/gv_find_me.h>
41
42static char *smyrnaDir;
43static char *smyrnaGlade;
44
45/* smyrnaPath:
46 * Construct pathname for smyrna data file.
47 * Base file name is given as suffix.
48 * The function resolves the directory containing the data files,
49 * and constructs a complete pathname.
50 * The returned string is malloced, so the application should free
51 * it later.
52 * Returns NULL on error.
53 */
54char *smyrnaPath(char *suffix) {
55 static size_t baselen;
56#ifdef _WIN32
57 char *pathSep = "\\";
58#else
59 char *pathSep = "/";
60#endif
61 assert(smyrnaDir);
62
63 if (baselen == 0) {
64 baselen = strlen(smyrnaDir) + 2;
65 }
66 size_t len = baselen + strlen(suffix);
67 char *buf = gv_calloc(len, sizeof(char));
68 snprintf(buf, len, "%s%s%s", smyrnaDir, pathSep, suffix);
69 return buf;
70}
71
72static char *useString = "Usage: smyrna [-v?] <file>\n\
73 -f<WxH:bits@rate> - full-screen mode\n\
74 -e - draw edges as splines if available\n\
75 -v - verbose\n\
76 -? - print usage\n";
77
78static void usage(int v) {
79 fputs(useString, stdout);
81}
82
83static char *Info[] = {
84 "smyrna", /* Program */
85 PACKAGE_VERSION, /* Version */
86 BUILDDATE /* Build Date */
87};
88
89static char *parseArgs(int argc, char *argv[], ViewInfo *viewinfo) {
90 int c;
91
92 while ((c = getopt(argc, argv, ":eKf:txvV?")) != -1) {
93 switch (c) {
94 case 'e':
95 viewinfo->drawSplines = 1;
96 break;
97 case 'v': // FIXME: deprecate and remove -v in future
98 break;
99 case 'f':
100 viewinfo->guiMode = GUI_FULLSCREEN;
101 viewinfo->optArg = optarg;
102 break;
103
104 case 'V':
105 fprintf(stderr, "%s version %s (%s)\n", Info[0], Info[1], Info[2]);
106 graphviz_exit(0);
107 break;
108 case '?':
109 if (optopt == '\0' || optopt == '?')
110 usage(0);
111 else {
112 fprintf(stderr, "smyrna: option -%c unrecognized\n", optopt);
113 usage(1);
114 }
115 break;
116 }
117 }
118
119 if (optind < argc)
120 return argv[optind];
121 else
122 return NULL;
123}
124
125static void windowedMode(int argc, char *argv[]) {
126 GdkGLConfig *glconfig;
127 /*combo box to show loaded graphs */
128 GtkComboBox *graphComboBox;
129
130 gtk_set_locale();
131 gtk_init(&argc, &argv);
132 if (!(smyrnaGlade))
133 smyrnaGlade = smyrnaPath("smyrna.glade");
134 xml = glade_xml_new(smyrnaGlade, NULL, NULL);
135
136 GtkWidget *gladewidget = glade_xml_get_widget(xml, "frmMain");
137 gtk_widget_show(gladewidget);
138 g_signal_connect(gladewidget, "destroy", G_CALLBACK(mQuitSlot), NULL);
139 glade_xml_signal_autoconnect(xml);
140 gtk_gl_init(0, 0);
141 /* Configure OpenGL framebuffer. */
142 glconfig = configure_gl();
143 gladewidget = glade_xml_get_widget(xml, "hbox11");
144
145 gtk_widget_hide(glade_xml_get_widget(xml, "vbox13"));
146 gtk_window_set_deletable(
147 (GtkWindow *)glade_xml_get_widget(xml, "dlgSettings"), 0);
148 gtk_window_set_deletable((GtkWindow *)glade_xml_get_widget(xml, "frmTVNodes"),
149 0);
150 create_window(glconfig, gladewidget);
151 change_cursor(GDK_TOP_LEFT_ARROW);
152
153#ifndef _WIN32
154 glutInit(&argc, argv);
155#endif
156
157 gladewidget = glade_xml_get_widget(xml, "hbox13");
158 graphComboBox = (GtkComboBox *)gtk_combo_box_new_text();
159 gtk_box_pack_end((GtkBox *)gladewidget, (GtkWidget *)graphComboBox, 1, 1, 10);
160 gtk_widget_show((GtkWidget *)graphComboBox);
161 view->graphComboBox = graphComboBox;
162
164 gtk_main();
165}
166
168static char *find_share(void) {
169
170#ifdef _WIN32
171 const char PATH_SEPARATOR = '\\';
172#else
173 const char PATH_SEPARATOR = '/';
174#endif
175
176 // find the path to the `smyrna` binary
177 char *smyrna_exe = gv_find_me();
178 if (smyrna_exe == NULL) {
179 fputs("failed to find path to self\n", stderr);
180 graphviz_exit(EXIT_FAILURE);
181 }
182
183 // assume it is of the form …/bin/smyrna[.exe] and construct
184 // …/share/graphviz/smyrna
185
186 char *slash = strrchr(smyrna_exe, PATH_SEPARATOR);
187 if (slash == NULL) {
188 fprintf(stderr, "no path separator in path to self, %s\n", smyrna_exe);
189 free(smyrna_exe);
190 graphviz_exit(EXIT_FAILURE);
191 }
192
193 *slash = '\0';
194 slash = strrchr(smyrna_exe, PATH_SEPARATOR);
195 if (slash == NULL) {
196 fprintf(stderr, "no path separator in directory containing self, %s\n",
197 smyrna_exe);
198 free(smyrna_exe);
199 graphviz_exit(EXIT_FAILURE);
200 }
201
202 *slash = '\0';
203 size_t share_len = strlen(smyrna_exe) + strlen("/share/graphviz/smyrna") + 1;
204 char *share = gv_alloc(share_len);
205 snprintf(share, share_len, "%s%cshare%cgraphviz%csmyrna", smyrna_exe,
206 PATH_SEPARATOR, PATH_SEPARATOR, PATH_SEPARATOR);
207 free(smyrna_exe);
208
209 return share;
210}
211
212int main(int argc, char *argv[]) {
213 smyrnaDir = getenv("SMYRNA_PATH");
214 if (!smyrnaDir) {
216 }
217
218 char *package_locale_dir;
219#ifdef G_OS_WIN32
220 {
221 char *package_prefix =
222 g_win32_get_package_installation_directory(NULL, NULL);
223 package_locale_dir =
224 g_build_filename(package_prefix, "share", "locale", NULL);
225 g_free(package_prefix);
226 }
227#else
228 package_locale_dir = g_build_filename(smyrnaDir, "locale", NULL);
229#endif /* # */
230#ifdef ENABLE_NLS
231 bindtextdomain(GETTEXT_PACKAGE, package_locale_dir);
232 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
233 textdomain(GETTEXT_PACKAGE);
234#endif
235 view = gv_alloc(sizeof(ViewInfo));
237 view->initFileName = parseArgs(argc, argv, view);
238 if (view->initFileName)
239 view->initFile = 1;
240
242 cb_glutinit(800, 600, &argc, argv, view->optArg);
243 else
244 windowedMode(argc, argv);
245 g_free(package_locale_dir);
246 graphviz_exit(0);
247}
248
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
Definition alloc.h:26
static void * gv_alloc(size_t size)
Definition alloc.h:47
char * suffix
Definition bcomps.c:66
static NORETURN void graphviz_exit(int status)
Definition exit.h:23
GdkGLConfig * configure_gl(void)
Definition gltemplate.c:310
void create_window(GdkGLConfig *glconfig, GtkWidget *vbox)
Definition gltemplate.c:339
static double len(glCompPoint p)
Definition glutils.c:150
int cb_glutinit(int w, int h, int *argcp, char *argv[], char *optArg)
Definition glutrender.c:222
void free(void *)
node NULL
Definition grammar.y:163
GladeXML * xml
Definition gui.c:22
char * gv_find_me(void)
Definition gv_find_me.c:65
platform abstraction for finding the path to yourself
static const char * usage
Definition gvpr.c:51
static char * smyrnaGlade
Definition main.c:43
static char * Info[]
Definition main.c:83
char * smyrnaPath(char *suffix)
Definition main.c:54
static char * smyrnaDir
path to directory containing smyrna data files
Definition main.c:42
static char * useString
Definition main.c:72
static char * parseArgs(int argc, char *argv[], ViewInfo *viewinfo)
Definition main.c:89
static void windowedMode(int argc, char *argv[])
Definition main.c:125
static char * find_share(void)
find an absolute path to where Smyrna auxiliary files are stored
Definition main.c:168
void change_cursor(GdkCursorType C)
void mQuitSlot(GtkWidget *widget, void *user_data)
#define GUI_FULLSCREEN
Definition smyrnadefs.h:209
ViewInfo * view
Definition viewport.c:37
char * optArg
Definition smyrnadefs.h:346
GtkComboBox * graphComboBox
Definition smyrnadefs.h:339
char * initFileName
Definition smyrnadefs.h:334
int drawSplines
Definition smyrnadefs.h:336
#define textdomain(String)
Definition support.h:23
#define bindtextdomain(Domain, Directory)
Definition support.h:27
int main()
void init_viewport(ViewInfo *vi)
Definition viewport.c:190