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