1 /*********************************************************
2  * cc90hfe (c) Teo Developers
3  *********************************************************
4  *
5  *  Copyright (C) 2012-2017 Yves Charriau, Fran�ois Mouret
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 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21 
22 /*
23  *  Module     : linux/gui.c
24  *  Version    : 0.7.0
25  *  Cr�� par   : Fran�ois Mouret 27/02/2013
26  *  Modifi� par: Fran�ois Mouret 26/07/2013 31/05/2015
27  *
28  *  Archive callback.
29  */
30 
31 
32 #ifndef SCAN_DEPEND
33    #include <stdio.h>
34    #include <string.h>
35    #include <unistd.h>
36    #include <stdlib.h>
37    #include <locale.h>
38    #include <gtk/gtk.h>
39    #include <gtk/gtkx.h>
40    #include <gdk/gdkx.h>
41    #include <X11/Xlib.h>
42 #endif
43 
44 #include "defs.h"
45 #include "main.h"
46 #include "std.h"
47 #include "ini.h"
48 #include "errors.h"
49 #include "option.h"
50 #include "encode.h"
51 #include "cc90.h"
52 #include "hfe.h"
53 #include "serial.h"
54 #include "linux/progress.h"
55 #include "linux/gui.h"
56 
57 GtkWidget *main_window;
58 
59 GtkWidget *archive_button;
60 GtkWidget *extract_button;
61 GtkWidget *install_button;
62 GtkWidget *progress_label;
63 GtkWidget *progress_bar;
64 GtkWidget *progress_button;
65 GtkWidget *not_thomson_side_0;
66 GtkWidget *not_thomson_side_1;
67 GtkWidget *retry_label;
68 GtkWidget *retry_spinbutton;
69 
70 
71 
gui_EnableRetry(int flag)72 static void gui_EnableRetry (int flag)
73 {
74     if ((gui.not_thomson_side[0] == TRUE) && (gui.not_thomson_side[1] == TRUE))
75     {
76         gtk_widget_set_sensitive (retry_label, FALSE);
77         gtk_widget_set_sensitive (retry_spinbutton, FALSE);
78     }
79     else
80     {
81         gtk_widget_set_sensitive (retry_label, flag);
82         gtk_widget_set_sensitive (retry_spinbutton, flag);
83     }
84 }
85 
86 
87 
on_spin_value_changed(GtkSpinButton * spin,gpointer user_data)88 static void on_spin_value_changed (GtkSpinButton *spin, gpointer user_data)
89 {
90     gui.read_retry_max = (int) gtk_spin_button_get_value (spin);
91     /* just in case the value is not an integer */
92     gtk_spin_button_set_value (spin, (gdouble)gui.read_retry_max);
93 }
94 
95 
96 
try_to_quit(GtkWidget * widget,GdkEvent * event,gpointer user_data)97 static gboolean try_to_quit (GtkWidget *widget, GdkEvent *event,
98                                    gpointer user_data)
99 {
100     int ret;
101     GtkWidget *dialog;
102 
103     if (progress_on == TRUE)
104     {
105         dialog = gtk_message_dialog_new_with_markup (
106                              GTK_WINDOW(main_window),
107                              GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
108                              GTK_MESSAGE_INFO,
109                              GTK_BUTTONS_OK_CANCEL,
110                              is_fr?encode_String(
111                              "Un processus est encore en cours d'ex�cution.\n" \
112                              "Voulez-vous vraiment quitter ?")
113                             :"A process is still running\n" \
114                              "Do you really want to quit ?",
115                              NULL);
116         ret = gtk_dialog_run (GTK_DIALOG(dialog));
117         gtk_widget_destroy (dialog);
118         if (ret == GTK_RESPONSE_CANCEL)
119             return TRUE;
120         progress_on = FALSE;
121         while (progress_dead == FALSE);
122     }
123     gtk_main_quit();
124     return FALSE;
125     (void)widget;
126     (void)event;
127     (void)user_data;
128 }
129 
130 
131 
not_thomson_side_toggled(GtkToggleButton * button,gpointer user_data)132 static void not_thomson_side_toggled (GtkToggleButton *button, gpointer user_data)
133 {
134     int *p = user_data;
135 
136     *p = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(button));
137     gui_EnableRetry (TRUE);
138 }
139 
140 
141 
142 /* udisplay_Window:
143  *   Cr�e la fen�tre principale.
144  */
display_window(void)145 static void display_window(void)
146 {
147     GtkWidget *widget, *frame;
148     GtkWidget *hbox, *hbox2, *vbox, *vbox2;
149 
150     main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
151     gtk_window_set_resizable (GTK_WINDOW(main_window), FALSE);
152     gtk_window_set_title (GTK_WINDOW(main_window), "CC90HFE");
153     gtk_widget_set_size_request (main_window, 300, -1);
154     gtk_widget_add_events (main_window, GDK_CONFIGURE);
155     g_signal_connect (G_OBJECT (main_window), "delete-event",
156                       G_CALLBACK (try_to_quit), NULL);
157 
158     /* bo�te verticale principale */
159     vbox=gtk_box_new(GTK_ORIENTATION_VERTICAL,5);
160     gtk_container_set_border_width( GTK_CONTAINER(vbox), 5);
161     gtk_container_add( GTK_CONTAINER(main_window), vbox);
162 
163     /* archiving button */
164     archive_button = gtk_button_new_with_label(
165                          is_fr?"Copier une disquette vers un fichier HFE"
166                               :"Copy a floppy onto a HFE file");
167     g_signal_connect(G_OBJECT(archive_button), "clicked",
168                      G_CALLBACK(archive_Callback), NULL);
169     gtk_box_pack_start( GTK_BOX(vbox), archive_button, FALSE, FALSE, 0);
170 
171     /* extracting button */
172     extract_button = gtk_button_new_with_label(
173                          is_fr?"Copier un fichier HFE vers une disquette"
174                               :"Copy a HFE file onto a floppy");
175     g_signal_connect(G_OBJECT(extract_button), "clicked",
176                      G_CALLBACK(extract_Callback), NULL);
177     gtk_box_pack_start( GTK_BOX(vbox), extract_button, FALSE, FALSE, 0);
178 
179     /* installing button */
180     install_button=gtk_button_new_with_label(
181                is_fr?"Installer CC90 sur le Thomson"
182                     :"Install CC90 on the Thomson");
183     g_signal_connect(G_OBJECT(install_button), "clicked",
184                      G_CALLBACK(install_Callback), NULL);
185     gtk_box_pack_start( GTK_BOX(vbox), install_button, FALSE, FALSE, 0);
186 
187     /* about button */
188     widget=gtk_button_new_with_label(is_fr?"A propos...":"About...");
189     g_signal_connect(G_OBJECT(widget), "clicked",
190                      G_CALLBACK(about_Callback), NULL);
191     gtk_box_pack_start( GTK_BOX(vbox), widget, FALSE, FALSE, 0);
192 
193     widget = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
194     gtk_box_pack_start (GTK_BOX(vbox), widget, FALSE, FALSE, 0);
195 
196     /* Frame verticale */
197     frame=gtk_frame_new ("Options");
198     gtk_box_pack_start (GTK_BOX(vbox), frame, TRUE, TRUE, 0);
199 
200     /* bo�te verticale */
201     vbox2=gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
202     gtk_box_set_homogeneous (GTK_BOX(vbox2), TRUE);
203     gtk_container_set_border_width( GTK_CONTAINER(vbox2), 5);
204     gtk_container_add( GTK_CONTAINER(frame), vbox2);
205 
206     /* bo�te horizontale */
207     hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
208     gtk_box_pack_start (GTK_BOX(vbox2), hbox, FALSE, FALSE, 0);
209 
210     /* Thomson side 0 disk check box */
211     not_thomson_side_0=gtk_check_button_new_with_label(
212         is_fr?"La face 0 n'est pas Thomson"
213              :"Side 0 is not Thomson like");
214     gtk_box_pack_start (GTK_BOX(hbox), not_thomson_side_0, FALSE, FALSE, 0);
215     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(not_thomson_side_0),
216                                   gui.not_thomson_side[0]);
217     g_signal_connect(G_OBJECT(not_thomson_side_0),
218                      "toggled",
219                      G_CALLBACK(not_thomson_side_toggled),
220                      (gpointer)&gui.not_thomson_side[0]);
221 
222     /* bo�te horizontale */
223     hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
224     gtk_box_pack_start (GTK_BOX(vbox2), hbox, FALSE, FALSE, 0);
225 
226     /* Thomson side 1 disk check box */
227     not_thomson_side_1=gtk_check_button_new_with_label(
228         is_fr?"La face 1 n'est pas Thomson"
229              :"Side 1 is not Thomson like");
230     gtk_box_pack_start (GTK_BOX(hbox), not_thomson_side_1, FALSE, FALSE, 0);
231     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(not_thomson_side_1),
232                                   gui.not_thomson_side[1]);
233     g_signal_connect(G_OBJECT(not_thomson_side_1),
234                      "toggled",
235                      G_CALLBACK(not_thomson_side_toggled),
236                      (gpointer)&gui.not_thomson_side[1]);
237 
238 
239     /* bo�te horizontale */
240     hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
241     gtk_box_pack_start (GTK_BOX(vbox2), hbox, FALSE, FALSE, 0);
242 
243     retry_label = gtk_label_new (is_fr?"Nombre de relectures maximum : "
244                                       :"Maximum count of rereadings : ");
245     gtk_box_pack_start (GTK_BOX(hbox), retry_label, FALSE, FALSE, 0);
246 
247     /* Retry number spin button */
248     retry_spinbutton = gtk_spin_button_new_with_range ((gdouble)1,
249                                                        (gdouble)15,
250                                                        (gdouble)1);
251     gtk_box_pack_start (GTK_BOX(hbox), retry_spinbutton, FALSE, FALSE, 0);
252     gtk_spin_button_set_value (GTK_SPIN_BUTTON(retry_spinbutton),
253                                (gdouble)gui.read_retry_max);
254     g_signal_connect(G_OBJECT(retry_spinbutton),
255                      "value-changed",
256                      G_CALLBACK(on_spin_value_changed),
257                      (gpointer)NULL);
258     gui_EnableRetry (TRUE);
259 
260     /* bo�te horizontale */
261     hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
262     gtk_box_pack_start (GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
263 
264     /* progress label */
265     progress_label=gtk_label_new ("");
266     gtk_box_pack_start (GTK_BOX(hbox), progress_label, FALSE, FALSE, 0);
267 
268     /* bo�te horizontale */
269     hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,5);
270     gtk_box_pack_start (GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
271 
272     /* bo�te horizontale */
273     hbox2=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,5);
274     gtk_box_pack_start (GTK_BOX(hbox), hbox2, TRUE, TRUE, 0);
275 
276     /* bo�te verticale */
277     vbox2=gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
278     gtk_box_set_homogeneous (GTK_BOX(vbox2), TRUE);
279     gtk_box_pack_start (GTK_BOX(hbox2), vbox2, TRUE, TRUE, 0);
280 
281     /* progress bar */
282     progress_bar = gtk_progress_bar_new ();
283     gtk_box_pack_start (GTK_BOX(vbox2), progress_bar, FALSE, FALSE, 0);
284 
285     /* bo�te horizontale */
286     hbox2=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,5);
287     gtk_box_pack_start (GTK_BOX(hbox), hbox2, FALSE, FALSE, 0);
288 
289     /* stop button */
290     progress_button=gtk_button_new ();
291     widget = gtk_image_new_from_icon_name ("process-stop", GTK_ICON_SIZE_BUTTON);
292     gtk_container_add( GTK_CONTAINER(progress_button), widget);
293     g_signal_connect(G_OBJECT(progress_button), "clicked",
294                      G_CALLBACK(progress_Stop), NULL);
295     gtk_box_pack_start( GTK_BOX(hbox2), progress_button, FALSE, FALSE, 0);
296 
297     gui_ResetProgress ();
298 
299     gtk_widget_show_all (main_window);
300 }
301 
302 
303 #ifdef DEBIAN_BUILD
copy_debian_file(const char filename[])304 static void copy_debian_file (const char filename[])
305 {
306     char *src_name = NULL;
307     char *dst_name = NULL;
308     FILE *src_file = NULL;
309     FILE *dst_file = NULL;
310     int c;
311 
312     src_name = std_strdup_printf ("/usr/share/cc90hfe/%s", filename);
313     dst_name = std_ApplicationPath (APPLICATION_DIR, filename);
314     if ((src_name != NULL) && (*src_name != '\0')
315      && (dst_name != NULL) && (*dst_name != '\0')
316      && (access (dst_name, F_OK) < 0))
317     {
318         src_file = fopen (src_name, "rb");
319         dst_file = fopen (dst_name, "wb");
320 
321         while ((src_file != NULL)
322             && (dst_file != NULL)
323             && ((c = fgetc(src_file)) != EOF))
324         {
325             fputc (c, dst_file);
326         }
327 
328         src_file = std_fclose (src_file);
329         dst_file = std_fclose (dst_file);
330     }
331     src_name = std_free (src_name);
332     dst_name = std_free (dst_name);
333 }
334 #endif
335 
336 
337 /* ------------------------------------------------------------------------- */
338 
339 
gui_SetProgressText(char * text)340 void gui_SetProgressText (char *text)
341 {
342     gtk_label_set_text (GTK_LABEL(progress_label), text);
343 }
344 
345 
gui_SetProgressBar(double value)346 void gui_SetProgressBar (double value)
347 {
348    gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progress_bar), value);
349 }
350 
351 
352 
gui_EnableButtons(int flag)353 void gui_EnableButtons (int flag)
354 {
355     gtk_widget_set_sensitive (archive_button, flag);
356     gtk_widget_set_sensitive (extract_button, flag);
357     gtk_widget_set_sensitive (install_button, flag);
358     gtk_widget_set_sensitive (not_thomson_side_0, flag);
359     gtk_widget_set_sensitive (not_thomson_side_1, flag);
360     gtk_widget_set_sensitive (progress_button, (flag == TRUE) ? FALSE : TRUE);
361     gui_EnableRetry (flag);
362 }
363 
364 
365 
gui_ResetProgress(void)366 void gui_ResetProgress (void)
367 {
368     gui_SetProgressText (is_fr?"En attente.":"Waiting.");
369     gui_SetProgressBar (0);
370     gui_EnableButtons (TRUE);
371 }
372 
373 
374 
gui_ProgressUpdate(int percent)375 void gui_ProgressUpdate (int percent)
376 {
377     progress_Update (percent);
378 }
379 
380 
381 
gui_ErrorDialog(char * message)382 void gui_ErrorDialog (char *message)
383 {
384     GtkWidget *dialog;
385 
386     dialog = gtk_message_dialog_new_with_markup (
387                          GTK_WINDOW(main_window),
388                          GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
389                          GTK_MESSAGE_ERROR,
390                          GTK_BUTTONS_CLOSE,
391                          encode_String(message),
392                          NULL);
393     (void)gtk_dialog_run (GTK_DIALOG(dialog));
394     gtk_widget_destroy (dialog);
395 }
396 
397 
398 
gui_InformationDialog(char * message)399 int gui_InformationDialog (char *message)
400 {
401     int ret;
402     GtkWidget *dialog;
403 
404     dialog = gtk_message_dialog_new_with_markup (
405                          GTK_WINDOW(main_window),
406                          GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
407                          GTK_MESSAGE_INFO,
408                          GTK_BUTTONS_OK_CANCEL,
409                          encode_String(message),
410                          NULL);
411     ret = gtk_dialog_run (GTK_DIALOG(dialog));
412     gtk_widget_destroy (dialog);
413     return (ret==GTK_RESPONSE_OK) ? TRUE : FALSE;
414 }
415 
416 
417 
418 /*************************************************************************
419  Main :
420  *************************************************************************/
main(int argc,char * argv[])421 int main (int argc, char *argv[])
422 {
423     char *lang;
424 
425     /* Repair current language */
426     lang=getenv("LANG");
427     if (lang==NULL)
428         lang="fr_FR";
429     setlocale(LC_ALL, "");
430     is_fr = (strncmp(lang,"fr",2)==0) ? 1 : 0;
431 
432     /* set current encoding */
433     encode_Set (CODESET_UTF8);
434 
435 #ifdef DEBIAN_BUILD
436     copy_debian_file ("cc90.sap");
437     copy_debian_file ("cc90.fd");
438     copy_debian_file ("cc90.hfe");
439 #endif
440 
441     main_InitAll ();
442     main_ConsoleReadCommandLine (argc, argv);
443     if (argc > 1)
444     {
445         main_Console ();
446     }
447     else
448     {
449         XInitThreads ();
450         gtk_init (&argc, &argv);
451         windowed_mode = 1;
452         ini_Load ();
453         display_window ();
454         gtk_main();
455     }
456     main_FreeAll ();
457     return EXIT_SUCCESS;
458 
459 }
460 
461