1 /*
2  * Xiphos Bible Study Tool
3  * gui.c - The heart of the gui.
4  *
5  * Copyright (C) 2000-2020 Xiphos Developer Team
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20  */
21 
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 
26 #include <gtk/gtk.h>
27 #include <glib/gi18n.h>
28 #include <locale.h>
29 #include <stdlib.h>
30 
31 /* ----------------------------------------------- */
32 /* do not #include "gui/debug_glib_null.h" in this */
33 /* file: here we define the replacement functions, */
34 /* so we need access to the real glib versions.    */
35 /* ----------------------------------------------- */
36 
37 #include "gui/gui.h"
38 #include "gui/dialog.h"
39 
40 #ifdef HAVE_DBUS
41 #include "gui/ipc.h"
42 static IpcObject *ipc;
43 #endif
44 
gui_init(int argc,char * argv[])45 void gui_init(int argc, char *argv[])
46 {
47 	static int gui_init_done = FALSE;
48 
49 	if (gui_init_done)
50 		return;
51 	gui_init_done = TRUE;
52 
53 #ifdef ENABLE_NLS
54 	bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
55 	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
56 	textdomain(GETTEXT_PACKAGE);
57 #endif
58 #ifdef WIN32
59 	gchar *locale_dir =
60 	    g_win32_get_package_installation_directory_of_module(NULL);
61 	locale_dir = g_strconcat(locale_dir, "\0", NULL);
62 	locale_dir = g_build_filename(locale_dir, "share", "locale", NULL);
63 	bindtextdomain(GETTEXT_PACKAGE, locale_dir);
64 	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
65 	textdomain(GETTEXT_PACKAGE);
66 	g_free(locale_dir);
67 #endif
68 	if (!gtk_init_with_args(&argc, &argv, NULL, NULL, NULL, NULL)) {
69 		exit(1);
70 	};
71 #ifdef HAVE_DBUS
72 	ipc = ipc_init_dbus_connection(ipc);
73 #endif
74 }
75 
gui_main(void)76 void gui_main(void)
77 {
78 	gtk_main();
79 }
80 
81 #ifdef DEBUG
82 
83 /* NOTE: these routines are here only and exactly because there is no other */
84 /* code in this file that needs the real glib versions.  if there is ever a */
85 /* reason for using g_str{dup,ing}_printf in this file, these functions     */
86 /* will need to be moved to some other file which does not need them.  this */
87 /* is because the file implementing replacements must not #include the .h   */
88 /* that induces access to the replacements via #define.                     */
89 
90 /* this is a total mind game: we redefine the standard use of glib functions */
91 /* so as to see our internal versions.  our internal versions scan for mis-  */
92 /* use of %s, i.e. (char*)NULL that should (by rights) cause crashes anyhow. */
93 
94 /* GIVE US THE CRASHES, PLEASE!  MYSTERY BUGS ARE EVIL!  glibc.helpfulness-- */
95 
XI_g_strdup_printf(const char * filename,int linenumber,const gchar * format,...)96 gchar *XI_g_strdup_printf(const char *filename,
97 			  int linenumber, const gchar *format, ...)
98 {
99 	gchar *buffer, *s;
100 	va_list args;
101 
102 	va_start(args, format);
103 	for (s = strchr(format, '%'); s; s = strchr(++s, '%')) {
104 		gchar *next = va_arg(args, gchar *);
105 		if ((next == (gchar *)NULL) && (*(s + 1) == 's')) {
106 			gchar *msg = g_strdup_printf("%s\n%s\n\n%s:%d \"%s\"",
107 						     _("BUG! Xiphos is about to crash due to a \"STRDUP\" error."),
108 						     _("Please report this error to the Xiphos team with:"),
109 						     filename, linenumber, format);
110 			gui_generic_warning_modal(msg);
111 			g_free(msg);
112 			abort();
113 		}
114 	}
115 	va_end(args);
116 
117 	/* real g_strdup_printf content */
118 	va_start(args, format);
119 	buffer = g_strdup_vprintf(format, args);
120 	va_end(args);
121 	return buffer;
122 }
123 
124 void
XI_g_string_printf(const char * filename,int linenumber,GString * string,const gchar * format,...)125 XI_g_string_printf(const char *filename,
126 		   int linenumber,
127 		   GString *string, const gchar *format, ...)
128 {
129 	gchar *s;
130 	va_list args;
131 
132 	va_start(args, format);
133 	for (s = strchr(format, '%'); s; s = strchr(++s, '%')) {
134 		gchar *next = va_arg(args, gchar *);
135 		if ((next == (gchar *)NULL) && (*(s + 1) == 's')) {
136 			gchar *msg = g_strdup_printf("%s\n%s\n\n%s:%d \"%s\"",
137 						     _("BUG! Xiphos is about to crash due to a \"STRING\" error."),
138 						     _("Please report this error to the Xiphos team with:"),
139 						     filename, linenumber, format);
140 			gui_generic_warning_modal(msg);
141 			g_free(msg);
142 			abort();
143 		}
144 	}
145 	va_end(args);
146 
147 	/* real g_string_printf content */
148 	g_string_truncate(string, 0);
149 	va_start(args, format);
150 	g_string_append_vprintf(string, format, args);
151 	va_end(args);
152 }
153 
154 #endif /* DEBUG */
155