"Fossies" - the Fresh Open Source Software Archive

Member "klavaro-3.13/src/main.c" (18 Apr 2021, 15661 Bytes) of package /linux/privat/klavaro-3.13.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "main.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.12_vs_3.13.

    1 /**************************************************************************/
    2 /*  Klavaro - a flexible touch typing tutor                               */
    3 /*  Copyright (C) 2005-2021 Felipe Emmanuel Ferreira de Castro            */
    4 /*                                                                        */
    5 /*  This file is part of Klavaro, which is a free software: you can       */
    6 /*  redistribute it and/or modify it under the terms of the GNU General   */
    7 /*  Public License as published by the Free Software Foundation, either   */
    8 /*  version 3 of the License, or (at your option) any later version.      */
    9 /*                                                                        */
   10 /*  Klavaro is distributed in the hope that it will be useful,            */
   11 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of        */
   12 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         */
   13 /*  GNU General Public License for more details (in the file COPYING).    */
   14 /*  You should have received a copy of the GNU General Public License     */
   15 /*  along with Klavaro.  If not, see <https://www.gnu.org/licenses/>      */
   16 /**************************************************************************/
   17 
   18 #include <string.h>
   19 #include <stdio.h>
   20 #include <stdlib.h>
   21 #include <glib.h>
   22 #include <glib/gstdio.h>
   23 #include <pango/pango-attributes.h>
   24 #include <gtk/gtk.h>
   25 #include <curl/curl.h>
   26 
   27 #include "auxiliar.h"
   28 #include "callbacks.h"
   29 #include "translation.h"
   30 #include "keyboard.h"
   31 #include "tutor.h"
   32 #include "accuracy.h"
   33 #include "top10.h"
   34 #include "main.h"
   35 
   36 /*******************************************************************************
   37  * Variables
   38  */
   39 GtkBuilder *gui;
   40 
   41 gchar *KEYB_CUSTOM;
   42 gchar *KEYB_EDIT;
   43 gchar *OTHER_DEFAULT;
   44 
   45 static GKeyFile *preferences = NULL;
   46 static GKeyFile *altcolor = NULL;
   47 static gboolean curl_ok;
   48 static gboolean velo_txt;
   49 static struct
   50 {
   51     gchar *user;
   52     gchar *stats;
   53     gchar *data;
   54     gchar *score;
   55 } path;
   56 
   57 /*******************************************************************************
   58  * Interface functions
   59  */
   60 gchar *
   61 main_path_user ()
   62 {
   63     return (path.user);
   64 }
   65 
   66 gchar *
   67 main_path_stats ()
   68 {
   69     return (path.stats);
   70 }
   71 
   72 gchar *
   73 main_path_data ()
   74 {
   75     return (path.data);
   76 }
   77 
   78 gchar *
   79 main_path_score ()
   80 {
   81     return (path.score);
   82 }
   83 
   84 gboolean
   85 main_curl_ok ()
   86 {
   87     return (curl_ok);
   88 }
   89 
   90 gboolean
   91 main_velo_txt ()
   92 {
   93     return (velo_txt);
   94 }
   95 
   96 gboolean
   97 main_preferences_exist (gchar * group, gchar * key)
   98 {
   99     return (g_key_file_has_key (preferences, group, key, NULL));
  100 }
  101 
  102 void
  103 main_preferences_remove (gchar * group, gchar * key)
  104 {
  105     g_key_file_remove_key (preferences, group, key, NULL);
  106 }
  107 
  108 gchar *
  109 main_preferences_get_string (gchar * group, gchar * key)
  110 {
  111     return (g_key_file_get_string (preferences, group, key, NULL));
  112 }
  113 
  114 void
  115 main_preferences_set_string (gchar * group, gchar * key, gchar * value)
  116 {
  117     g_key_file_set_string (preferences, group, key, value);
  118 }
  119 
  120 gint
  121 main_preferences_get_int (gchar * group, gchar * key)
  122 {
  123     return (g_key_file_get_integer (preferences, group, key, NULL));
  124 }
  125 
  126 void
  127 main_preferences_set_int (gchar * group, gchar * key, gint value)
  128 {
  129     g_key_file_set_integer (preferences, group, key, value);
  130 }
  131 
  132 gboolean
  133 main_preferences_get_boolean (gchar * group, gchar * key)
  134 {
  135     return (g_key_file_get_boolean (preferences, group, key, NULL));
  136 }
  137 
  138 void
  139 main_preferences_set_boolean (gchar * group, gchar * key, gboolean value)
  140 {
  141     g_key_file_set_boolean (preferences, group, key, value);
  142 }
  143 
  144 gboolean
  145 main_altcolor_exist (gchar * group, gchar * key)
  146 {
  147     return (g_key_file_has_key (altcolor, group, key, NULL));
  148 }
  149 
  150 gchar *
  151 main_altcolor_get_string (gchar * group, gchar * key)
  152 {
  153     return (g_key_file_get_string (altcolor, group, key, NULL));
  154 }
  155 
  156 
  157 gboolean
  158 main_altcolor_get_boolean (gchar * group, gchar * key)
  159 {   
  160     return (g_key_file_get_boolean (altcolor, group, key, NULL));
  161 }
  162 
  163 void
  164 main_altcolor_set_boolean (gchar * group, gchar * key, gboolean value)
  165 {
  166     g_key_file_set_boolean (altcolor, group, key, value);
  167 }
  168 
  169 void
  170 main_preferences_save ()
  171 {
  172     gchar *tmp_name;
  173     FILE *fh;
  174 
  175     /* Save preferences
  176      */
  177     assert_user_dir ();
  178     tmp_name = g_build_filename (main_path_user (), "preferences.ini", NULL);
  179     fh = (FILE *) g_fopen (tmp_name, "w");
  180     if (fh == NULL)
  181         g_warning ("couldn't save your preferences at the user folder:\n %s", tmp_name);
  182     else
  183     {
  184         g_free (tmp_name);
  185         tmp_name = NULL;
  186         tmp_name = g_key_file_to_data (preferences, NULL, NULL);
  187         if (tmp_name != NULL)
  188             fputs (tmp_name, fh);
  189         else
  190             g_warning ("no preferences to be saved!");
  191         fclose (fh);
  192     }
  193     g_free (tmp_name);
  194 
  195     /* Save altcolor
  196      */
  197     tmp_name = g_build_filename (main_path_user (), "altcolor.ini", NULL);
  198     fh = (FILE *) g_fopen (tmp_name, "w");
  199     if (fh == NULL)
  200         g_warning ("couldn't save your altcolor file at the user folder:\n %s", tmp_name);
  201     else
  202     {
  203         g_free (tmp_name);
  204         tmp_name = NULL;
  205         tmp_name = g_key_file_to_data (altcolor, NULL, NULL);
  206         if (tmp_name != NULL)
  207             fputs (tmp_name, fh);
  208         else
  209             g_warning ("no altcolors to be saved!");
  210         fclose (fh);
  211     }
  212     g_free (tmp_name);
  213 }
  214 
  215 /*
  216  * End of interface, start of private functions
  217  */
  218 
  219 /**********************************************************************
  220  * Initialize the value of the global variables
  221  */
  222 static void
  223 main_initialize_global_variables ()
  224 {
  225     gchar *tmp;
  226     FILE *fh;
  227 
  228     /* Set the home user dir
  229      */
  230     path.user = g_build_filename (g_get_user_config_dir (), "klavaro", NULL);
  231     if (!g_file_test (path.user, G_FILE_TEST_IS_DIR))
  232     {
  233         if (g_mkdir_with_parents (path.user, DIR_PERM) == -1)
  234             g_error ("Sorry, not able to create the user config dir: %s", path.user);
  235     }
  236 
  237     /* Set the home user stats dir (~/.local/share dir)
  238      */
  239     if (UNIX_OK)
  240         path.stats = g_build_filename (g_get_user_data_dir (), "klavaro", NULL);
  241     else
  242         path.stats = g_build_filename (g_get_user_config_dir (), "klavaro", NULL);
  243     if (!g_file_test (path.stats, G_FILE_TEST_IS_DIR))
  244     {
  245         g_mkdir_with_parents (path.stats, DIR_PERM);
  246     }
  247 
  248     /* Get a valid data path.
  249      * First searches the path at the source directory.
  250      */
  251     path.data = g_build_filename ("..", "data", NULL);
  252     tmp = g_build_filename (path.data, "basic_lessons.txt", NULL);
  253     if (!g_file_test (tmp, G_FILE_TEST_EXISTS))
  254     {
  255         g_free (path.data);
  256         g_free (tmp);
  257         path.data = g_build_filename (PACKAGE_DATA_DIR, PACKAGE, NULL);
  258         tmp = g_build_filename (path.data, "basic_lessons.txt", NULL);
  259     }
  260     if (! g_file_test (tmp, G_FILE_TEST_EXISTS))
  261         g_error ("couldn't find a data file at the data path:\n %s", tmp);
  262     g_free (tmp);
  263 
  264     /* Get a valid scoring path.
  265      */
  266     path.score = g_build_filename (path.stats, "ksc", NULL);
  267     if (!g_file_test (path.score, G_FILE_TEST_IS_DIR))
  268     {
  269         g_mkdir_with_parents (path.score, DIR_PERM);
  270     }
  271 
  272     /* Retrieve saved preferences or initial one
  273      */
  274     preferences = g_key_file_new ();
  275     tmp = g_build_filename (main_path_user (), "preferences.ini", NULL);
  276     if (!g_file_test (tmp, G_FILE_TEST_EXISTS))
  277     {
  278         g_free (tmp);
  279         tmp = g_strdup ("/etc/klavaro/preferences.ini");
  280     }
  281     g_key_file_load_from_file (preferences, tmp, G_KEY_FILE_NONE, NULL);
  282     g_free (tmp);
  283 
  284     /* Retrieve saved alternative colors or initial ones
  285      */
  286     altcolor = g_key_file_new ();
  287     tmp = g_build_filename (main_path_user (), "altcolor.ini", NULL);
  288     if (!g_file_test (tmp, G_FILE_TEST_EXISTS))
  289     {
  290         g_free (tmp);
  291         tmp = g_build_filename ("/etc/klavaro/altcolor.ini", NULL);
  292     }
  293     if (!g_file_test (tmp, G_FILE_TEST_EXISTS))
  294     {
  295         g_free (tmp);
  296         tmp = g_build_filename (main_path_data (), "altcolor.ini", NULL);
  297     }
  298     g_key_file_load_from_file (altcolor, tmp, G_KEY_FILE_NONE, NULL);
  299     g_free (tmp);
  300 
  301     /* Other initializations
  302      */
  303     trans_init_lang_name_code ();
  304     trans_init_language_env ();
  305     srand (time (0));
  306     tutor_init_timers ();
  307 
  308     KEYB_CUSTOM = g_strdup (_("(Custom)"));
  309     KEYB_EDIT = g_strdup (_("(Edit custom)"));
  310     OTHER_DEFAULT = g_strdup (_("(Default)"));
  311 }
  312 
  313 static void
  314 main_gtkbuilder_translation_workaround ()
  315 {
  316     gchar *lb;
  317     GSList *ls;
  318     GSList *it;
  319     GtkWidget *wg;
  320 
  321     ls = gtk_builder_get_objects (gui);
  322     it = ls;
  323     do
  324     {
  325         if (G_OBJECT_TYPE (it->data) == GTK_TYPE_LABEL)
  326         {
  327             lb = (gchar *) gtk_label_get_label (GTK_LABEL (it->data));
  328             if (lb[0] != '\0')
  329                 gtk_label_set_text_with_mnemonic (GTK_LABEL (it->data), _(lb));
  330         }
  331         else if (G_OBJECT_TYPE (it->data) == GTK_TYPE_ENTRY)
  332         {
  333             lb = gtk_entry_get_icon_tooltip_text (GTK_ENTRY (it->data), GTK_ENTRY_ICON_SECONDARY);
  334             if (lb)
  335             {
  336                 if (lb[0] != '\0')
  337                     gtk_entry_set_icon_tooltip_text (GTK_ENTRY (it->data), GTK_ENTRY_ICON_SECONDARY, _(lb));
  338             }
  339         }
  340         else if (G_OBJECT_TYPE (it->data) == GTK_TYPE_WINDOW)
  341             gtk_window_set_title (GTK_WINDOW (it->data), _(gtk_window_get_title (GTK_WINDOW (it->data))));
  342 
  343         if (GTK_IS_WIDGET (it->data))
  344         {
  345             wg = GTK_WIDGET (it->data);
  346             if (gtk_widget_get_has_tooltip (wg))
  347                 gtk_widget_set_tooltip_text (wg, _(gtk_widget_get_tooltip_text (wg)));
  348         }
  349 
  350         it = g_slist_next (it);
  351     } while (it);
  352 
  353     g_slist_free (ls);
  354 }
  355 
  356 /*******************************************************************************
  357  * Initialize some interface widgets
  358  */
  359 static void
  360 main_window_init ()
  361 {
  362     gchar *tmp = NULL;
  363     gchar *ttip = NULL;
  364     PangoAttrList *palist;
  365 
  366     /* Workaround to make GtkBuilder translate all text, on Windows :-(
  367      */
  368     if (! UNIX_OK)
  369         main_gtkbuilder_translation_workaround ();
  370 
  371     /* Set the language
  372      */
  373     trans_set_combo_language ();
  374 
  375     /* Set keyboard
  376      */
  377     keyb_create_virtual_keys ();
  378     hints_init ();
  379 
  380     /* Set if speech is enabled
  381      */
  382     callbacks_shield_set (TRUE);
  383     if (!main_preferences_exist ("interface", "speech"))
  384         main_preferences_set_boolean ("interface", "speech", TRUE);
  385     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (get_wg ("checkbutton_speech")),
  386                 main_preferences_get_boolean ("interface", "speech"));
  387     tmp = g_strdup (dngettext (PACKAGE, "Dictation mode (depends on this speech synthesizer: %s)",
  388                         "Dictation mode (depends on one of these speech synthesizers: %s)", 1));
  389     ttip = g_strdup_printf (tmp, "Espeak");
  390     g_free (tmp);
  391     gtk_widget_set_tooltip_text (get_wg ("checkbutton_speech"), ttip);
  392     callbacks_shield_set (FALSE);
  393     
  394     /* Set the initial keyboard to use
  395      */
  396     keyb_set_combo_kbd ("combobox_kbd_country", "combobox_kbd_variant");
  397     keyb_set_combo_kbd ("combobox_keyboard_country", "combobox_keyboard_variant");
  398 
  399     /* Set window icons
  400      */
  401     gtk_window_set_default_icon_name ("klavaro");
  402 
  403     /* Set pixmaps
  404      */
  405     set_pixmap ("image_altcolor", "altcolor.png");
  406     set_pixmap ("image_fluid", "fluid.png");
  407     set_pixmap ("image_keyboard", "key.png");
  408     set_pixmap ("image_other", "other.png");
  409     set_pixmap ("image_progress", "progress.png");
  410     set_pixmap ("image_top10", "top10.png");
  411 
  412     /* Set Top10 TreeViews and Combo
  413      */
  414     top10_init ();
  415 
  416     /* Set big and bold labels
  417      */
  418     pango_parse_markup ("<big><b>----------------------------------------------------------------</b></big>",
  419                 -1, 0, &palist, NULL, NULL, NULL);
  420     gtk_label_set_attributes (GTK_LABEL (get_wg ("label_keyboard_title")), palist);
  421     gtk_label_set_attributes (GTK_LABEL (get_wg ("label_main_intro")), palist);
  422     gtk_label_set_attributes (GTK_LABEL (get_wg ("label_main_basic")), palist);
  423     gtk_label_set_attributes (GTK_LABEL (get_wg ("label_main_adapt")), palist);
  424     gtk_label_set_attributes (GTK_LABEL (get_wg ("label_main_velo")), palist);
  425     gtk_label_set_attributes (GTK_LABEL (get_wg ("label_main_fluid")), palist);
  426 
  427     /* Set main labels (for translation)
  428      */
  429     tmp = g_strdup_printf ("0 - %s", _("Introduction"));
  430     gtk_label_set_text (GTK_LABEL (get_wg ("label_main_intro")), tmp);
  431     g_free (tmp);
  432     tmp = g_strdup_printf ("1 - %s", _("Basic course"));
  433     gtk_label_set_text (GTK_LABEL (get_wg ("label_main_basic")), tmp);
  434     g_free (tmp);
  435     tmp = g_strdup_printf ("2 - %s", _("Adaptability"));
  436     gtk_label_set_text (GTK_LABEL (get_wg ("label_main_adapt")), tmp);
  437     g_free (tmp);
  438     if (velo_txt)
  439         tmp = g_strdup_printf ("3 - %s (TXT)", _("Speed"));
  440     else
  441         tmp = g_strdup_printf ("3 - %s", _("Speed"));
  442     gtk_label_set_text (GTK_LABEL (get_wg ("label_main_velo")), tmp);
  443     g_free (tmp);
  444     tmp = g_strdup_printf ("4 - %s", _("Fluidity"));
  445     gtk_label_set_text (GTK_LABEL (get_wg ("label_main_fluid")), tmp);
  446     g_free (tmp);
  447 
  448     /* Set version
  449      */
  450     gtk_about_dialog_set_version (GTK_ABOUT_DIALOG (get_obj ("aboutdialog")), VERSION);
  451 
  452     /* For remembering the window's position
  453      */
  454     gtk_widget_show (get_wg ("window_main"));
  455     window_restore ("main");
  456     
  457     /* Altcolor toggle button 
  458      */
  459     if (!main_altcolor_exist ("colors", "altcolor"))
  460         main_altcolor_set_boolean ("colors", "altcolor", FALSE);
  461     if (main_altcolor_get_boolean ("colors", "altcolor") == TRUE)
  462         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (get_wg ("togglebutton_altcolor")), TRUE);
  463 
  464     /* Run last used module
  465      */
  466     if (!main_preferences_exist ("interface", "autostart"))
  467         main_preferences_set_boolean ("interface", "autostart", FALSE);
  468     if (!main_preferences_exist ("interface", "exercise"))
  469         main_preferences_set_int ("interface", "exercise", 1);
  470     if (main_preferences_get_boolean ("interface", "autostart"))
  471     {
  472         switch (main_preferences_get_int ("interface", "exercise"))
  473         {
  474         case TT_BASIC:
  475             on_button_basic_clicked (NULL, NULL);
  476             break;
  477         case TT_ADAPT:
  478             on_button_adapt_clicked (NULL, NULL);
  479             break;
  480         case TT_VELO:
  481             on_button_velo_clicked (NULL, NULL);
  482             break;
  483         case TT_FLUID:
  484             on_button_fluid_clicked (NULL, NULL);
  485             break;
  486         }
  487     }
  488 
  489     /* Set accuracy accumulators
  490      */
  491     accur_init ();
  492 }
  493 
  494 /*******************************************************************************
  495  * Main program
  496  */
  497 int
  498 main (int argc, char *argv[])
  499 {
  500     gchar *tmp;
  501     gboolean success = FALSE;
  502     gboolean show_version = FALSE;
  503     GOptionContext *opct;
  504     GOptionEntry option[] = {
  505         {"version", 'v', 0, G_OPTION_ARG_NONE, &show_version, "Version", NULL},
  506         {"velotxt", 'x', 0, G_OPTION_ARG_NONE, &velo_txt, "Speed TXT", NULL},
  507         {NULL}
  508     };
  509     GError *gerr = NULL;
  510 
  511     /* Localization
  512      */
  513 #ifdef ENABLE_NLS
  514     bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
  515     bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
  516     textdomain (GETTEXT_PACKAGE);
  517 #endif
  518 
  519     /* Command-line arguments
  520      */
  521     opct = g_option_context_new ("\t");
  522     g_option_context_set_translation_domain (opct, GETTEXT_PACKAGE);
  523     g_option_context_add_main_entries (opct, option, GETTEXT_PACKAGE);
  524     g_option_context_add_group (opct, gtk_get_option_group (TRUE));
  525     g_setenv ("NO_AT_BRIDGE", "1", FALSE); /* to eliminate annoying accessibility bus warning */
  526     if (g_option_context_parse (opct, &argc, &argv, &gerr) == FALSE)
  527     {
  528         g_printf ("%s\n", gerr->message);
  529         g_printf ("klavaro -h\n");
  530         return 0;
  531     }
  532 
  533     if (show_version)
  534     {
  535         g_printf (VERSION"\n");
  536         //g_printf (PACKAGE_LOCALE_DIR"\n");
  537         return 0;
  538     }
  539 
  540     curl_ok = curl_global_init (CURL_GLOBAL_WIN32) == CURLE_OK ? TRUE : FALSE;
  541 
  542     main_initialize_global_variables ();    /* Here the locale is got. */
  543 
  544     /* Create all the interface stuff
  545      */
  546     gui = gtk_builder_new ();
  547     gtk_builder_set_translation_domain (gui, NULL);
  548 
  549     tmp = g_build_filename (main_path_data (), "klavaro.glade", NULL);
  550     if (g_file_test (tmp, G_FILE_TEST_IS_REGULAR))
  551         success = gtk_builder_add_from_file (gui, tmp, NULL);
  552     else
  553         g_error ("GUI file not found. Aborting.\n %s", tmp);
  554     if (!success)
  555         g_error ("GUI file found but couldn't create the GUI. Aborting.");
  556     if (!g_module_supported ())
  557         g_error ("GUI created but can't connect signals.");
  558     g_free (tmp);
  559     gtk_builder_connect_signals (gui, NULL);
  560 
  561     main_window_init ();    /* and initialize its parameters */
  562 
  563     gtk_main ();
  564 
  565     return 0;
  566 }
  567 
  568 /*******************************************************************************
  569  * Quit the application
  570  */
  571 void
  572 main_window_pass_away ()
  573 {
  574     main_preferences_save ();
  575     accur_close ();
  576     g_rmdir ("tmp/klavaro");
  577     if (curl_ok) curl_global_cleanup ();
  578     g_print ("\nAdiaux!\n");
  579     exit (0);
  580 }