1 /*                             */
2 /* xemeraldia    ----- main.c  */
3 /*                             */
4 
5 #ifdef HAVE_CONFIG_H
6 #include <config.h>
7 #endif
8 
9 #define _GNU_SOURCE
10 
11 #include "games.h"
12 #include <stdlib.h>
13 #include <string.h>
14 #ifdef HAVE_PWD_H
15 #include <pwd.h>
16 #endif
17 #include <unistd.h>
18 #include <errno.h>
19 
20 #ifdef HAVE_GETOPT_LONG_ONLY
21 #include <getopt.h>
22 #endif
23 
24 #define char const char
25 #include "bitmaps/xemeraldia.xpm"
26 #undef char
27 
28 AppData  app_data = { .usescorefile = TRUE, .scorefile = HIGH_SCORE_TABLE };
29 char    *name, *programname;
30 
31 static GdkPixbuf *xemeraldia_icon;
32 
Quit()33 void Quit()
34 {
35 	gtk_main_quit();
36 }
37 
About(void)38 static void About(void)
39 {
40 	GtkWidget *dialog, *label, *img, *hbox;
41 	dialog = gtk_dialog_new_with_buttons(_("About XEmeraldia"),
42 		GTK_WINDOW(topLevel),
43 		GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
44 		GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT,
45 		NULL);
46 
47 	hbox = gtk_hbox_new(FALSE, 2);
48 
49 	img = gtk_image_new_from_pixbuf(xemeraldia_icon);
50 	gtk_misc_set_padding(GTK_MISC(img), 20, 10);
51 	gtk_box_pack_start(GTK_BOX(hbox), img, FALSE,
52 		FALSE, 0);
53 
54 	label = gtk_label_new(NULL);
55 
56 	gtk_label_set_markup(GTK_LABEL(label),
57 		_("<span size='xx-large' weight='bold'>xemeraldia</span>"));
58 
59 	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE,
60 		FALSE, 0);
61 
62 	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE,
63 		FALSE, 0);
64 
65 	label = gtk_label_new(NULL);
66 
67 	gtk_label_set_markup(GTK_LABEL(label),
68 		_("Drop the blocks.  If you drop a square on top of one "
69 		"of the same color, they (as well as any neighboring "
70 		"blocks of the same color) will both be shaken by an "
71 		"“impact”.  The first impact will cause fractures; the "
72 		"second will cause the block(s) to dissolve.\n\n"
73 
74 		"You can either use the arrow keys or vi-style (hjkl) "
75 		"keys to move/rotate the blocks.  “s” or “p” will "
76 		"pause the game, and if your boss comes along, “q” can "
77 		"be used to avoid an unpleasant confrontation.\n"
78 		"\n"
79 		"Author: Yuuki Tomikawa &lt;tommy@huie.hokudai.ac.jp>\n"
80 		"\n"
81 		"Ported to GTK+ 2.x in 2003\n"
82 		"by Nicolás Lichtmaier &lt;nick@reloco.com.ar>\n"
83 		)
84 	);
85 
86 	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
87 	gtk_misc_set_padding(GTK_MISC(label), 20, 10);
88 	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE,
89 		TRUE, 0);
90 
91 	gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
92 	gtk_widget_show_all(dialog);
93 	gtk_dialog_run(GTK_DIALOG(dialog));
94 	gtk_widget_destroy(dialog);
95 }
96 
get_x_color(const char * cn,GdkColor * color)97 void get_x_color(const char *cn, GdkColor *color)
98 {
99 	gdk_color_parse(cn, color);
100 	gdk_colormap_alloc_color(gdk_colormap_get_system(), color, FALSE, TRUE);
101 }
102 
103 #ifdef HAVE_GETOPT_LONG_ONLY
104 struct option options[] =
105 {
106 	{"score", FALSE, &(app_data.usescorefile), TRUE},
107 	{"noscore", FALSE, &(app_data.usescorefile), FALSE},
108 	{0, 0, 0, 0}
109 };
110 #endif
111 
main(int argc,char * argv[])112 int  main (int argc, char *argv[])
113 {
114 	struct passwd *who;
115 
116 	programname = argv[0];
117 
118 	bindtextdomain(PACKAGE, LOCALEDIR);
119 	bind_textdomain_codeset(PACKAGE, "UTF-8");
120 	textdomain(PACKAGE);
121 
122 	open_high_scores_file();
123 
124 	gtk_init(&argc, &argv);
125 
126 #if 0
127 	gtk_rc_parse_string(
128 			"style \"xemeraldia\" { \n"
129 			"bg[NORMAL] =  \"SteelBlue1\"\n"
130 			"font_name = \"Courier bold 12\"\n"
131 			"text[NORMAL] =  \"white\"\n"
132 			"fg[NORMAL] =  \"white\"\n"
133 			"}\n"
134 			"style \"xemeraldia-button\" { \n"
135 			"bg[NORMAL] =  \"SkyBlue\"\n"
136 			"font_name = \"Courier bold 12\"\n"
137 			"text[NORMAL] =  \"black\"\n"
138 			"fg[NORMAL] =  \"black\"\n"
139 			"GtkWidget::interior-focus = 0\n"
140 			"}\n"
141 			"style \"xemeraldia-frame\" { \n"
142 			"bg[NORMAL] =  \"DodgerBlue2\"\n"
143 			"}\n"
144 			"class \"GtkWidget\" style \"xemeraldia\"\n"
145 			"class \"GtkButton\" style \"xemeraldia-button\"\n"
146 			"widget \"*.GtkButton.GtkLabel\" style \"xemeraldia-button\"\n"
147 			"widget \"*.GtkFrame\" style \"xemeraldia-frame\"\n"
148 			"widget \"*.GtkFrame.*\" style \"xemeraldia-frame\"\n"
149 			);
150 #endif
151 
152 #ifdef HAVE_GETOPT_LONG_ONLY
153 	while(getopt_long_only(argc, argv, "", options, NULL) != EOF);
154 #else
155 	if(argc>=2 && !strcmp(argv[1], "-noscore"))
156 		app_data.usescorefile = FALSE;
157 #endif
158 
159 	if(!f_scores)
160 	{
161 		if(app_data.usescorefile)
162 		{
163 			app_data.usescorefile = FALSE;
164 			fprintf(stderr, _("%s: Couldn't open high score file %s (%s)\n"),
165 				programname, app_data.scorefile, strerror(errno_scores) );
166 			fprintf(stderr, _("%s: No High score file.  Use '-noscore' to avoid this message.\n"),
167 				programname );
168 		}
169 	} else
170 	{
171 		if(!app_data.usescorefile)
172 		{
173 			fclose(f_scores);
174 			f_scores = NULL;
175 		}
176 	}
177 
178 	topLevel = gtk_window_new(GTK_WINDOW_TOPLEVEL);
179 	gtk_window_set_title(GTK_WINDOW(topLevel), "xemeraldia");
180 	gtk_window_set_resizable(GTK_WINDOW(topLevel), FALSE);
181 
182 	xemeraldia_icon = gdk_pixbuf_new_from_xpm_data(icon);
183 	gtk_window_set_icon(GTK_WINDOW(topLevel), xemeraldia_icon);
184 
185 /*	g_log_set_always_fatal(G_LOG_LEVEL_MASK); */
186 
187 	get_x_color("red", &app_data.block1pixel);
188 	get_x_color("blue", &app_data.block2pixel);
189 	get_x_color("green", &app_data.block3pixel);
190 	get_x_color("yellow", &app_data.block4pixel);
191 	get_x_color("violet", &app_data.block5pixel);
192 	get_x_color("sky blue", &app_data.block6pixel);
193 	get_x_color("orange", &app_data.starpixel);
194 
195 	board_pix = gdk_pixmap_new(NULL, WIN_WIDTH, WIN_HEIGHT, gdk_visual_get_system()->depth);
196 	background = gdk_pixmap_new(NULL, WIN_WIDTH, WIN_HEIGHT, gdk_visual_get_system()->depth);
197 
198 	  initGTK(topLevel);
199 
200 	g_signal_connect(G_OBJECT(quit), "clicked", G_CALLBACK(Quit), NULL);
201 	g_signal_connect(G_OBJECT(topLevel), "delete-event", G_CALLBACK(Quit), NULL);
202 	g_signal_connect(G_OBJECT(start), "clicked", G_CALLBACK(StartGame), NULL);
203 	g_signal_connect(G_OBJECT(about), "clicked", G_CALLBACK(About), NULL);
204 	if(app_data.usescorefile)
205 		g_signal_connect(G_OBJECT(scores), "clicked", G_CALLBACK(PrintHighScores), NULL);
206 
207 	gtk_widget_show_all(topLevel);
208 
209 	initXlib ();
210 	who  = getpwuid (getuid ());
211 	name = who -> pw_name;
212 	read_high_scores ();
213 
214 	gtk_main();
215 	return 0;
216 }
217