1 /*
2 main.c
3 13.3.99 tn
4 */
5
6 #ifdef HAVE_CONFIG_H
7 # include <config.h>
8 #endif
9
10 #include "largefile.h"
11
12 #if HAVE_LOCALE_H
13 #include <locale.h>
14 #else
15 # define setlocale(Category, Locale)
16 #endif
17 #include "gettext.h"
18
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <signal.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25
26 #if ENABLE_NLS
27 # define _(String) gettext (String)
28 # define N_(String) gettext_noop (String)
29 #else
30 # define _(String) (String)
31 # define N_(String) (String)
32 #endif
33
34 #include <gtk/gtk.h>
35 #include <gdk/gdk.h>
36 #include <gdk-pixbuf/gdk-pixbuf.h>
37 #include <gdk/gdkprivate.h>
38 #include "xcdrdata.h"
39 #include "xcdroast.h"
40 #include "main.h"
41 #include "../xpms/xcdricon.xpm"
42
43 GtkWidget *toplevel;
44 GtkWidget *splitspace;
45 GtkWidget *sidespace;
46 GtkWidget *workspace;
47 setup_data_t setupdata;
48 current_set_t curset;
49
50 gint debug;
51 gint submenu;
52 gint bigfonts;
53 gint oldfontcode;
54 gint altdevscan;
55 gint no_versioncheck;
56
57 static gint lastxsize, lastysize;
58
59 extern gchar sharedir[MAXLINE];
60 extern gchar rootconfig[MAXLINE];
61 extern gchar xcdroast_version_loaded[MAXLINE];
62
63
64
65 /* exit-button handler */
66
menu_exit(GtkWidget * widget,gpointer data)67 static void menu_exit(GtkWidget *widget, gpointer data) {
68 gint ret;
69
70 ret = show_dialog(ICO_QUEST,_("Really quit X-CD-Roast?"),
71 T_YES,T_NO,NULL,0);
72
73 if (ret == 0) {
74 dolog(1,"Exiting...\n");
75 remove_tmp_xcdr_files();
76 gtk_main_quit();
77 }
78 }
79
menu_exit_now(GtkWidget * widget,gpointer data)80 static void menu_exit_now(GtkWidget *widget, gpointer data) {
81
82 dolog(1,"Exiting...\n");
83 gtk_main_quit();
84
85 }
86
87
88 /* replacement of gtk_exit with more cleanups */
89
my_do_gtk_exit(gint code,gint textonly)90 static void my_do_gtk_exit(gint code, gint textonly) {
91
92 #if (defined(__MACH__) && defined(__APPLE__))
93 show_restart_autodiskmount(textonly);
94 #endif
95
96 gtk_exit(code);
97 }
98
99
100 /* set the width of the sidebar - relative to width of toplevel */
101
set_sidebar_width()102 void set_sidebar_width() {
103 gint x, y;
104 gint val;
105
106 /* check if we are already realized */
107 if (GTK_WIDGET(toplevel)->window == NULL) {
108 val = 150;
109 } else {
110 /* set relative to new size */
111 gdk_window_get_size(GTK_WIDGET(toplevel)->window,&x,&y);
112
113 /* workaround for a little gtk bug - in some chases
114 the current window size is reported wrongly as 200x200 */
115 if (x == 200 && y == 200) {
116 if (bigfonts == 0)
117 x = XCDR_TOPLEVEL_X0;
118 else
119 x = XCDR_TOPLEVEL_X1;
120 }
121 val = (x*150)/790;
122 }
123
124 gtk_widget_set_usize(sidespace,val,0);
125 }
126
127
128 /* called everytime some window resizes - we check if the toplevel
129 changed and set the sidebar to the value we want. This way
130 we can dynamically resize and the layout does not change */
131
resize_handler(GtkWidget * widget,gpointer data)132 static void resize_handler(GtkWidget *widget, gpointer data) {
133 gint x, y;
134
135 /* check if we are already realized */
136 if (GTK_WIDGET(toplevel)->window == NULL)
137 return;
138
139 gdk_window_get_size(GTK_WIDGET(toplevel)->window,&x,&y);
140
141 /* size of toplevel changed? */
142 if (x != lastxsize || y != lastysize) {
143 /* remember new size */
144 lastxsize = x;
145 lastysize = y;
146
147 /* set sidebar width to new value */
148 set_sidebar_width();
149 }
150 }
151
152
153 /* setup-button handler */
154
menu_setup(GtkWidget * widget,gpointer data)155 static void menu_setup(GtkWidget *widget, gpointer data) {
156
157 dolog(2,"Entering setup\n");
158 create_setup();
159 }
160
161
162 /* duplicate-button handler */
163
menu_duplicate(GtkWidget * widget,gpointer data)164 static void menu_duplicate(GtkWidget *widget, gpointer data) {
165
166 dolog(2,"Entering duplicate cd\n");
167 create_duplicate();
168 }
169
170
171 /* create-button handler */
172
menu_create(GtkWidget * widget,gpointer data)173 static void menu_create(GtkWidget *widget, gpointer data) {
174
175 dolog(2,"Entering create cd\n");
176 create_create();
177 }
178
179
180 /* set the pixmap icon */
181
set_wm_icon()182 static void set_wm_icon() {
183 GtkStyle *style;
184 GdkBitmap *bitmap;
185 GdkPixmap *pixmap;
186 GdkColormap *colormap;
187 GdkColor wait_color={0,0,0,0};
188
189 style=gtk_widget_get_style(GTK_WIDGET(toplevel));
190 pixmap=gdk_pixmap_create_from_xpm_d(GTK_WIDGET(toplevel)->window,
191 &bitmap, &style->bg[GTK_STATE_NORMAL], xcdricon_xpm);
192 colormap = gtk_widget_get_colormap(GTK_WIDGET(toplevel));
193 gdk_color_alloc (colormap, &wait_color);
194 gdk_window_set_icon(GTK_WIDGET(toplevel)->window, (GdkWindow *)NULL, pixmap, bitmap);
195 }
196
197
198 /* draw the main-menu */
199
create_main(gint confignotloaded)200 void create_main(gint confignotloaded) {
201 GtkWidget *side_t;
202 GtkWidget *side_t_btn1;
203 GtkWidget *side_t_btn2;
204 GtkWidget *side_t_btn3;
205 GtkWidget *side_t_btn4;
206 GtkWidget *work_t;
207 GtkWidget *work_t_l1;
208 GtkWidget *work_t_l2;
209 GdkPixmap *p;
210 GdkBitmap *m;
211 GdkPixbuf *im;
212 GtkWidget *xcdroast_logo;
213 /*
214 GtkWidget *burnproof_logo;
215 GtkWidget *logoalign;
216 */
217 gchar tmp[MAXLINE];
218
219
220 submenu = 0;
221 clear_sidespace();
222 clear_workspace();
223
224 side_t = gtk_table_new(10,1, TRUE);
225 gtk_table_set_row_spacings(GTK_TABLE(side_t),10);
226 gtk_box_pack_start(GTK_BOX(sidespace), side_t,TRUE,TRUE,0);
227
228 side_t_btn1 = gtk_button_new_with_label (_("Setup"));
229 if (!curset.isProDVD) {
230 side_t_btn2 = gtk_button_new_with_label (_("Duplicate CD"));
231 side_t_btn3 = gtk_button_new_with_label (_("Create CD"));
232 } else {
233 side_t_btn2 = gtk_button_new_with_label (_("Duplicate CD/DVD"));
234 side_t_btn3 = gtk_button_new_with_label (_("Create CD/DVD"));
235 }
236 side_t_btn4 = gtk_button_new_with_label (_("Exit"));
237
238 gtk_signal_connect (GTK_OBJECT (side_t_btn1), "clicked",
239 GTK_SIGNAL_FUNC(menu_setup),NULL);
240 gtk_signal_connect (GTK_OBJECT (side_t_btn2), "clicked",
241 GTK_SIGNAL_FUNC(menu_duplicate),NULL);
242 gtk_signal_connect (GTK_OBJECT (side_t_btn3), "clicked",
243 GTK_SIGNAL_FUNC(menu_create),NULL);
244 gtk_signal_connect (GTK_OBJECT (side_t_btn4), "clicked",
245 GTK_SIGNAL_FUNC(menu_exit_now),NULL);
246
247 gtk_table_attach_defaults(GTK_TABLE(side_t), side_t_btn1, 0,1,4,5);
248 gtk_widget_show(side_t_btn1);
249 define_tooltip(side_t_btn1,_("Setup your hardware and system defaults"));
250
251 gtk_table_attach_defaults(GTK_TABLE(side_t), side_t_btn2, 0,1,5,6);
252 gtk_widget_show(side_t_btn2);
253 define_tooltip(side_t_btn2,_("Make an exact copy of a CD (data and audio)"));
254
255 gtk_table_attach_defaults(GTK_TABLE(side_t), side_t_btn3, 0,1,6,7);
256 gtk_widget_show(side_t_btn3);
257 define_tooltip(side_t_btn3,_("Create and arrange your own CD (data and audio)"));
258
259 gtk_table_attach_defaults(GTK_TABLE(side_t), side_t_btn4, 0,1,8,9);
260 gtk_widget_show(side_t_btn4);
261 define_tooltip(side_t_btn4,_("Quit X-CD-Roast"));
262
263 gtk_widget_show(side_t);
264 gtk_widget_show(sidespace);
265
266
267 /* draw the workspace */
268
269 work_t = gtk_table_new(10,10, TRUE);
270 gtk_box_pack_start(GTK_BOX(workspace), work_t,TRUE,FALSE,0);
271
272 /* load a gif-image and put into a pixmap */
273 g_snprintf(tmp,MAXLINE,"%s/%s", sharedir, XCDRLOGO);
274 #if GTK_MAJOR_VERSION < 2
275 im=gdk_pixbuf_new_from_file(tmp);
276 #else
277 im=gdk_pixbuf_new_from_file(tmp,NULL);
278 #endif
279 if (im) {
280 gdk_pixbuf_render_pixmap_and_mask(im, &p, &m, 128);
281 xcdroast_logo = gtk_pixmap_new(p,m);
282 gdk_pixbuf_unref(im);
283 } else {
284 xcdroast_logo = gtk_label_new("[LOGO]");
285 }
286 gtk_table_attach_defaults(GTK_TABLE(work_t), xcdroast_logo, 0,10,0,4);
287 gtk_misc_set_alignment(GTK_MISC(xcdroast_logo),0.5f, 0.5f);
288 gtk_widget_show(xcdroast_logo);
289
290 /* load a gif-image and put into a pixmap */
291 /*
292 g_snprintf(tmp,MAXLINE,"%s/%s", sharedir, BURNPROOFLOGO);
293 im=gdk_pixbuf_new_from_file(tmp);
294 if (im) {
295 gdk_pixbuf_render_pixmap_and_mask(im, &p, &m, 128);
296 burnproof_logo = gtk_pixmap_new(p,m);
297 gdk_pixbuf_unref(im);
298 } else {
299 burnproof_logo = gtk_label_new("[BURNPROOF]");
300 }
301 logoalign = gtk_alignment_new(1.0,1.0,0,0);
302 gtk_container_add(GTK_CONTAINER(logoalign), burnproof_logo);
303 gtk_table_attach_defaults(GTK_TABLE(work_t), logoalign, 0,10,9,10);
304 gtk_widget_show(burnproof_logo);
305 gtk_widget_show(logoalign);
306 */
307 g_snprintf(tmp,MAXLINE,_("Version %s"),XCDROAST_VERSION);
308 work_t_l1=gtk_label_new(tmp);
309 gtk_label_set_justify(GTK_LABEL(work_t_l1),GTK_JUSTIFY_CENTER);
310 gtk_table_attach_defaults(GTK_TABLE(work_t), work_t_l1, 0,10,4,5);
311 set_font_and_color(work_t_l1,BIGFONT,"red");
312
313 work_t_l2=gtk_label_new(_("(c) 1996-2008 by T. Niederreiter\n\nhttp://www.xcdroast.org"));
314 gtk_label_set_justify(GTK_LABEL(work_t_l2),GTK_JUSTIFY_CENTER);
315 gtk_table_attach_defaults(GTK_TABLE(work_t), work_t_l2, 0,10,5,6);
316
317 gtk_widget_show(work_t_l1);
318 gtk_widget_show(work_t_l2);
319
320 gtk_widget_show(work_t);
321 gtk_widget_show(workspace);
322
323 if (confignotloaded) {
324 gtk_widget_set_sensitive(side_t_btn2, FALSE);
325 gtk_widget_set_sensitive(side_t_btn3, FALSE);
326 }
327 }
328
329
330 /* signal handler to gracefully exit on ctrl-c */
331
my_signal_exit(gint isignal)332 static void my_signal_exit(gint isignal) {
333
334 g_print("Caught SIGINT, exiting...\n");
335 remove_tmp_xcdr_files();
336 my_do_gtk_exit(isignal, 1);
337 }
338
339
340 /* main */
341
main(gint argc,gchar * argv[])342 gint main(gint argc, gchar *argv[]) {
343 GtkWidget *w;
344 gint confignotloaded, nrm;
345 #if 0
346 gchar *keyenv;
347 #endif
348 gchar tmp[MAXLINE];
349 gchar tmp2[MAXLINE];
350 #if GTK_MAJOR_VERSION < 2
351 GtkStyle *style;
352 #else
353 PangoRectangle ink_rect;
354 PangoLayout *layout;
355 #endif
356 #if (defined(__MACH__) && defined(__APPLE__))
357 gint stat;
358 #endif
359
360 #if ENABLE_NLS
361 #if GTK_MAJOR_VERSION < 2
362 bindtextdomain (PACKAGE, LOCALEDIR);
363 textdomain (PACKAGE);
364 #else
365 bindtextdomain (PACKAGE, LOCALEDIR);
366 bind_textdomain_codeset (PACKAGE, "utf8");
367 textdomain (PACKAGE);
368 #endif
369 #endif
370 gtk_set_locale();
371 gtk_init(&argc,&argv);
372
373 #if (defined(__MACH__) && defined(__APPLE__))
374 /* dont use xshm on darwin -> its broken */
375 /* from gdk-private */
376 gdk_use_xshm = FALSE;
377 #endif
378
379 /* get rid of badmatch() errors */
380 gdk_rgb_init();
381 gtk_widget_set_default_visual(gdk_rgb_get_visual());
382 gtk_widget_set_default_colormap(gdk_rgb_get_cmap());
383
384 /* private init for xcdroast */
385 confignotloaded = init(argc, argv, &nrm, &altdevscan);
386
387 w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
388 /* save this pointer for future reference */
389 toplevel = w;
390
391 lastxsize = 0;
392 lastysize = 0;
393
394 /* check which font size we are running */
395 #if GTK_MAJOR_VERSION < 2
396
397 style = gtk_widget_get_style(toplevel);
398 if (gdk_char_height(style->font,'|') > 12) {
399 /* our font is higher as 12 pixels */
400 bigfonts = 1;
401 } else {
402 bigfonts = 0;
403 }
404 #else
405
406 /* create dummy layout just to measure the current font */
407 layout = gtk_widget_create_pango_layout(toplevel, "|");
408 pango_layout_get_extents(layout, NULL, &ink_rect);
409
410 if (PANGO_PIXELS(ink_rect.height) > 16)
411 bigfonts = 1;
412 else
413 bigfonts = 0;
414 #endif
415
416 gtk_widget_realize(toplevel);
417 set_wm_icon();
418 set_xcdr_title(w, NULL, -1);
419
420 #if (defined(__MACH__) && defined(__APPLE__))
421 /* on Mac OS X interactively disable the autodiskmount daemon */
422
423 /* use altdevscan variable to disable the daemon handling at all */
424 while (1 && altdevscan == 1) {
425 stat = create_autodiskmount_handler();
426
427 if (stat == -1)
428 continue;
429
430 if (stat == 1) {
431 break;
432 } else {
433 gtk_exit(1);
434 }
435 }
436 #endif
437
438 if (bigfonts == 0) {
439 /* size for 75dpi fonts */
440 gtk_widget_set_usize(GTK_WIDGET(w),
441 XCDR_TOPLEVEL_X0,XCDR_TOPLEVEL_Y0);
442 } else {
443 /* size for 100dpi fonts */
444 gtk_widget_set_usize(GTK_WIDGET(w),
445 XCDR_TOPLEVEL_X1,XCDR_TOPLEVEL_Y1);
446 }
447
448
449 gtk_container_border_width(GTK_CONTAINER(w),10);
450
451 gtk_signal_connect (GTK_OBJECT(w), "destroy",
452 GTK_SIGNAL_FUNC (gtk_exit), NULL);
453
454 gtk_signal_connect (GTK_OBJECT(w), "delete_event",
455 GTK_SIGNAL_FUNC(menu_exit), NULL);
456
457 gtk_signal_connect (GTK_OBJECT(w), "size_request",
458 GTK_SIGNAL_FUNC(resize_handler), NULL);
459
460
461 splitspace = gtk_hpaned_new();
462 gtk_container_add(GTK_CONTAINER(w),splitspace);
463 #if GTK_MAJOR_VERSION < 2
464 gtk_paned_handle_size(GTK_PANED(splitspace),0);
465 #endif
466 gtk_paned_gutter_size(GTK_PANED(splitspace),20);
467
468 /* left side */
469 sidespace = gtk_vbox_new(FALSE,0);
470 gtk_paned_add1(GTK_PANED(splitspace), sidespace);
471 set_sidebar_width();
472
473 /* right side */
474 workspace = gtk_vbox_new(FALSE,0);
475 gtk_paned_add2(GTK_PANED(splitspace), workspace);
476
477 /* check if screen-size is big enough */
478 if (check_screensize(bigfonts) && no_versioncheck == 0) {
479 strncpy(tmp2, _("You need at least a screen resolution of\n%dx%d to run X-CD-Roast.\n\nSee the man-page on how to override that requirement.\n\nExiting now..."), MAXLINE);
480
481 if (bigfonts == 0) {
482 g_snprintf(tmp,MAXLINE,tmp2, 800, 600);
483 } else {
484 g_snprintf(tmp,MAXLINE,tmp2, 1024, 768);
485 }
486 show_dialog(ICO_ERROR,tmp,T_OK,NULL,NULL,0);
487 my_do_gtk_exit(1, 0);
488 }
489
490 if (confignotloaded) {
491 #if !(defined(__MACH__) && defined(__APPLE__)) && (USE_NONROOTMODE == 1)
492 if (isroot()) {
493 /* scan for devices */
494 create_device_scanning(altdevscan, 0, 1, NULL);
495
496 /* first start for user root - ask him about nrm */
497 create_nonroot_configurator(nrm,0);
498 /* now show that no configfile exists yet */
499 show_dialog(ICO_INFO, _("No root configuration file found!\nPlease enter Setup and don't forget to add users\nwho may also use X-CD-Roast."), T_OK, NULL, NULL, 0);
500 } else {
501 #endif
502 /* scan for devices */
503 create_device_scanning(altdevscan, 0, 1, NULL);
504
505 show_dialog(ICO_INFO, _("No configuration file found!\nPlease enter Setup."), T_OK, NULL, NULL, 0);
506
507 #if !(defined(__MACH__) && defined(__APPLE__)) && (USE_NONROOTMODE == 1)
508 }
509 #endif
510 } else {
511 /* check if the configfile is for current version of xcdroast */
512 if (strcmp(XCDROAST_VERSION, xcdroast_version_loaded) != 0) {
513
514 /* first start of new version for user root - ask him about nrm */
515 #if !(defined(__MACH__) && defined(__APPLE__)) && (USE_NONROOTMODE == 1)
516 if (isroot()) {
517 create_nonroot_configurator(nrm,0);
518 }
519 #endif
520 /* scan for devices */
521 create_device_scanning(altdevscan, 0, 1, NULL);
522
523 g_snprintf(tmp,MAXLINE,_("Configuration file for incorrect version %s found!\nPlease enter Setup and create an updated configuration."), xcdroast_version_loaded);
524 show_dialog(ICO_INFO, tmp, T_OK, NULL, NULL, 0);
525 strcpy(xcdroast_version_loaded,"");
526 confignotloaded = 1;
527 if (isroot()) {
528 /* if config is from old version, we can
529 assume that it still got the wrong perms */
530 /* fix them */
531 chmod(rootconfig, 0644);
532 }
533 }
534
535 /* now check if our config is matching the current hardware */
536 #if 0
537 if (verify_loaded_config() == 1) {
538 /* scsi-bus changed */
539 show_dialog(ICO_WARN, _("Something on the SCSI-Bus has changed. Please check\nyour writer and reader configuration in Setup."), T_OK, NULL, NULL, 0);
540 strcpy(xcdroast_version_loaded,"");
541 confignotloaded = 1;
542 }
543 #endif
544 if (verify_loaded_config2() == 1) {
545 /* image-dirs changed */
546 show_dialog(ICO_WARN, _("The image-directories do not match the current system.\nPlease check their configuration in Setup."), T_OK, NULL, NULL, 0);
547 strcpy(xcdroast_version_loaded,"");
548 confignotloaded = 1;
549 }
550
551 }
552
553 create_main(confignotloaded);
554
555 gtk_widget_show(splitspace);
556 gtk_widget_show(w);
557
558 /* set new size from config? (only works after window is shown) */
559 if (setupdata.option_savepos &&
560 setupdata.mainwindow.width != -1 &&
561 setupdata.mainwindow.height != -1 &&
562 setupdata.mainwindow.x != -1 &&
563 setupdata.mainwindow.y != -1) {
564
565 gdk_window_move_resize(GTK_WIDGET(w)->window,
566 setupdata.mainwindow.x,
567 setupdata.mainwindow.y,
568 setupdata.mainwindow.width,
569 setupdata.mainwindow.height);
570 }
571
572
573
574 /* let the screen update now */
575 while (gtk_events_pending())
576 gtk_main_iteration();
577
578 /* show disclaimer (old disclaimer nr 288) */
579 /*
580 if (show_dialog(ICO_WARN, _("DISCLAIMER: This is just an unfinished version of the new X-CD-Roast 0.98.\nBut it is already more stable and offers more features as the current\nrelease 0.96ex. Please visit http://www.xcdroast.org for updates and\n more detailed information about this alpha-version.\n\nBut because there are still some of the important features missing,\nI do ask - do you really want to continue?"), T_YES, T_NO, NULL, 1) == 1) {
581 my_do_gtk_exit(1, 0);
582 }
583 */
584
585 /* warn about non-existing LFS support in dvd mode */
586 if ((curset.isProDVD & 1) && sizeof(off_t) != 8) {
587 show_dialog(ICO_WARN, _("Warning: Your system is not able to create files larger\nthan 2 GB. Writing DVDs will therefore not possible."), T_OK, NULL, NULL, 0);
588 }
589
590 /* if we are in DVD mode, check if the security-key is set */
591 #if 0
592 if (curset.isProDVD == 1) {
593 keyenv = getenv("CDR_SECURITY");
594 if (keyenv == NULL) {
595 show_dialog(ICO_WARN, _("Warning: You have not entered a cdrecord-ProDVD key in setup.\nPlease see the FAQ on how to obtain your free key.\nYou also have to renew the key every few months because it got an\nexpire date. You will not be able to properly write DVDs without it."), T_OK, NULL, NULL, 0);
596 }
597
598 }
599 #endif
600
601 dolog(1,"Starting X-CD-Roast\n");
602
603 /* install a signal handler to catch CTRL-C */
604 signal (SIGINT, my_signal_exit) ;
605
606 gtk_main();
607
608 my_do_gtk_exit(0, 0);
609 return 0;
610 }
611