"Fossies" - the Fresh Open Source Software Archive

Member "klavaro-3.13/src/basic.c" (18 Apr 2021, 9854 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 "basic.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 /*
   19  * Basic course
   20  */
   21 #include <string.h>
   22 #include <stdlib.h>
   23 #include <stdio.h>
   24 #include <math.h>
   25 #include <glib.h>
   26 #include <glib/gstdio.h>
   27 #include <gtk/gtk.h>
   28 
   29 #include "auxiliar.h"
   30 #include "main.h"
   31 #include "keyboard.h"
   32 #include "tutor.h"
   33 #include "basic.h"
   34 
   35 #define MAX_BASIC_CHAR_SET (8 * 14)
   36 struct
   37 {
   38     gint lesson;
   39     gunichar char_set[MAX_BASIC_CHAR_SET];
   40     glong char_set_size;
   41     gboolean lesson_increased;
   42 } basic;
   43 
   44 /*******************************************************************************
   45  * Interface functions
   46  */
   47 gint
   48 basic_get_lesson ()
   49 {
   50     return (basic.lesson);
   51 }
   52 
   53 void
   54 basic_set_lesson (gint lesson)
   55 {
   56     if (lesson >= 0)
   57     {
   58         basic.lesson = lesson;
   59         main_preferences_set_int ("tutor", "basic_lesson", lesson);
   60     }
   61 }
   62 
   63 gunichar *
   64 basic_get_char_set ()
   65 {
   66     return (basic.char_set);
   67 }
   68 
   69 gboolean
   70 basic_get_lesson_increased ()
   71 {
   72     return (basic.lesson_increased);
   73 }
   74 
   75 void
   76 basic_set_lesson_increased (gboolean state)
   77 {
   78     basic.lesson_increased = state;
   79 }
   80 
   81 /*******************************************************************************
   82  * Initialize basic vars
   83  */
   84 void
   85 basic_init ()
   86 {
   87     /* Retrieve the last lesson where the student had selected.
   88      */
   89     basic.lesson_increased = FALSE;
   90 
   91     if (main_preferences_exist ("tutor", "basic_lesson"))
   92         basic.lesson = main_preferences_get_int ("tutor", "basic_lesson");
   93     else
   94         basic_set_lesson (1);
   95     basic_init_char_set ();
   96 }
   97 
   98 /**********************************************************************
   99  * Read the characters to be used with the current basic.lesson
  100  */
  101 gint
  102 basic_init_char_set ()
  103 {
  104     gint i, j, k;
  105     gchar line_str[16];
  106     gchar *lesson_file;
  107     gchar *lesson_str;
  108     gunichar *tmpuc;
  109     FILE *fh;
  110     GtkWidget *wg;
  111 
  112     /*
  113      * Custom lessons
  114      */
  115     wg = get_wg ("togglebutton_edit_basic_lesson");
  116     if (basic.lesson > 43 && basic.lesson <= MAX_BASIC_LESSONS)
  117     {
  118         lesson_file = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "basic_lesson_%i.txt",
  119                     main_path_user (), basic.lesson);
  120         if (g_file_get_contents (lesson_file, &lesson_str, NULL, NULL))
  121         {
  122             tmpuc = g_utf8_to_ucs4_fast (lesson_str, -1, &basic.char_set_size);
  123             if (basic.char_set_size > MAX_BASIC_CHAR_SET)
  124                 basic.char_set_size = MAX_BASIC_CHAR_SET;
  125             for (i = j = 0; i < basic.char_set_size; i++)
  126                 if (g_unichar_isgraph (tmpuc[i]))
  127                     basic.char_set[j++] = tmpuc[i];
  128             basic.char_set[j] = L'\0';
  129             basic.char_set_size = j;
  130             g_free (tmpuc);
  131             g_free (lesson_str);
  132         }
  133         else
  134         {
  135             basic.char_set[0] = L' ';
  136             basic.char_set[1] = L' ';
  137             basic.char_set[2] = L'\0';
  138             basic.char_set_size = 2;
  139         }
  140         g_free (lesson_file);
  141 
  142         gtk_widget_set_sensitive (wg, TRUE);
  143         return (-1);
  144     }
  145     gtk_widget_set_sensitive (wg, FALSE);
  146 
  147     /*
  148      * Open the lesson file
  149      */
  150     lesson_file = g_build_filename (main_path_data (), "basic_lessons.txt", NULL);
  151     fh = (FILE *) g_fopen (lesson_file, "r");
  152     g_free (lesson_file);
  153     if (!fh)
  154         g_error ("couldn't find the basic lessons' file.");
  155 
  156     /*
  157      * Search the lesson
  158      */
  159     for (i = 1; i < basic.lesson; i++)
  160         for (j = 0; j < 11; j++)
  161             if (!(fgets (line_str, 16, fh)))
  162                 break;
  163 
  164     /*
  165      * Pass heading line
  166      */
  167     if (!(fgets (line_str, 16, fh)))
  168     {
  169         basic.char_set[0] = L'\0';
  170         basic.char_set_size = 0;
  171         fclose (fh);
  172         return (-1);
  173     }
  174 
  175     /*
  176      * Get chars, lower set
  177      */
  178     for (k = 0, i = 0; i < 4; i++)
  179     {
  180         if (!(fgets (line_str, 16, fh)))
  181         {
  182             basic.char_set[0] = L'\0';
  183             basic.char_set_size = 0;
  184             fclose (fh);
  185             return (-1);
  186         }
  187         for (j = 0; j < 14; j++)
  188         {
  189             if (line_str[j] == '1' && g_unichar_isgraph (keyb_get_lochars (i, j)))
  190                 basic.char_set[k++] = g_unichar_tolower (keyb_get_lochars (i, j));
  191         }
  192     }
  193 
  194     /*
  195      * Pass blank line
  196      */
  197     if (!(fgets (line_str, 16, fh)))
  198     {
  199         basic.char_set[0] = L'\0';
  200         basic.char_set_size = 0;
  201         fclose (fh);
  202         return (-1);
  203     }
  204 
  205     /*
  206      * Get chars, upper set
  207      */
  208     for (i = 0; i < 4; i++)
  209     {
  210         if (!(fgets (line_str, 16, fh)))
  211         {
  212             basic.char_set[0] = L'\0';
  213             basic.char_set_size = 0;
  214             fclose (fh);
  215             return (-1);
  216         }
  217         for (j = 0; j < 14; j++)
  218             if (line_str[j] == '1' && g_unichar_isgraph (keyb_get_upchars (i, j)))
  219                 basic.char_set[k++] = g_unichar_tolower (keyb_get_upchars (i, j));
  220     }
  221     fclose (fh);
  222 
  223     basic.char_set[k] = L'\0';
  224     basic.char_set_size = k;
  225     return (0);
  226 }
  227 
  228 /**********************************************************************
  229  * Save the lesson's character set defined in the custom lesson entry,
  230  * for the current lesson
  231  */
  232 void
  233 basic_save_lesson (gchar * charset)
  234 {
  235     gchar *lesson_file;
  236     FILE *fh;
  237 
  238     lesson_file = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "basic_lesson_%i.txt", main_path_user (), basic.lesson);
  239     fh = (FILE *) g_fopen (lesson_file, "w");
  240     if (fh == NULL)
  241         g_warning ("couldn't save the file:\n %s", lesson_file);
  242     else
  243     {
  244         fprintf (fh, "%s", charset);
  245         fclose (fh);
  246         if (strlen (charset) < 2)
  247             g_unlink (lesson_file);
  248     }
  249     g_free (lesson_file);
  250 }
  251 
  252 /**********************************************************************
  253  * Put the lesson's characters at the main screen
  254  */
  255 #define N_LINES 8
  256 void
  257 basic_draw_lesson ()
  258 {
  259     gint i, j, k, len;
  260     gint idx, rnd;
  261     gchar *ut8_tmp;
  262     gunichar sentence[9 * 6 + 4];
  263     gunichar char_pool[2*(N_LINES * 9 * 5)];
  264     GtkTextBuffer *buf;
  265 
  266     buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (get_wg ("text_tutor")));
  267 
  268     len = basic.char_set_size;
  269     if (len < 2)
  270     {
  271         g_warning ("No character set for this lesson.");
  272         return;
  273     }
  274 
  275     if (basic.char_set[0] == basic.char_set[1]) 
  276     {
  277         ut8_tmp = g_strconcat (_("This custom lesson is empty."
  278                       " You can define two or more different characters "
  279                       "to generate a personal practice."
  280                       " Press the editting button in the upper-right corner."), 
  281                 keyb_get_utf8_paragraph_symbol (), "\n", NULL);
  282         gtk_text_buffer_insert_at_cursor (buf, ut8_tmp, -1);
  283         gtk_text_buffer_insert_at_cursor (buf, ut8_tmp, -1);
  284         gtk_text_buffer_insert_at_cursor (buf, ut8_tmp, -1);
  285         gtk_text_buffer_insert_at_cursor (buf, ut8_tmp, -1);
  286         g_free (ut8_tmp);
  287         return;
  288     }
  289 
  290     /*
  291      * Draw the lines as sentences
  292      */
  293     memmove (char_pool, basic.char_set, len * sizeof (gunichar));
  294     if (len > 4 && len < 14)
  295     {
  296         memmove (char_pool+len, basic.char_set, len * sizeof (gunichar));
  297         len *= 2;
  298     }
  299     sentence[9 * 6] = L'\n';
  300     sentence[9 * 6 + 1] = L'\0';
  301     sentence[9 * 6 + 2] = L'\0';
  302     for (i = 0; i < N_LINES; i++)
  303     {           /* lines (sentences) */
  304         idx = 0;
  305         for (j = 0; j < 9; j++)
  306         {       /* words */
  307             for (k = 0; k < 5; k++)
  308             {   /* letters */
  309                 rnd = rand () % len;
  310                 sentence[idx++] = char_pool[rnd];
  311                 len--;
  312                 char_pool[rnd] = char_pool[len];
  313                 if (len == 0)
  314                 {
  315                     len = basic.char_set_size;
  316                     memmove (char_pool, basic.char_set, len * sizeof (gunichar));
  317                     if (len > 4 && len < 14)
  318                     {
  319                         memmove (char_pool+len, basic.char_set, len * sizeof (gunichar));
  320                         len *= 2;
  321                     }
  322                 }
  323                 if (keyb_is_diacritic (sentence[idx-1]))
  324                 {
  325                     if (tutor_is_tibetan())
  326                     {
  327                         if (k > 0 && keyb_is_vowel(sentence[idx-1]) && keyb_is_vowel(sentence[idx-2]) )
  328                         {
  329                             sentence[idx-1] = TIBETAN_WORD_DELIMITER;
  330                         }
  331                     }   
  332                     else
  333                     {
  334                         sentence[idx-1] = L' ';
  335                     }
  336                 }
  337             }
  338             if (j == 8)
  339                 sentence[idx] = UPSYM;
  340             else
  341                 sentence[idx] = tutor_is_tibetan() ? TIBETAN_WORD_DELIMITER : L' ';
  342             idx++;
  343         }
  344         ut8_tmp = g_ucs4_to_utf8 (sentence, -1, NULL, NULL, NULL);
  345         gtk_text_buffer_insert_at_cursor (buf, ut8_tmp, -1);
  346         g_free (ut8_tmp);
  347         if (len == 2 && i >= N_LINES/2-1)
  348             break;
  349     }
  350 }
  351 
  352 /**********************************************************************
  353  * Put on the screen the final comments
  354  */
  355 void
  356 basic_comment (gdouble accuracy)
  357 {
  358     gchar *tmp_str;
  359     GtkLabel *wg_label;
  360     GtkWidget *wg;
  361     GtkTextBuffer *buf;
  362 
  363     /*
  364      * Comments
  365      */
  366     if (accuracy < tutor_goal_accuracy ())
  367         tmp_str = g_strdup (":-(\n");
  368     else
  369     {
  370         basic_set_lesson (basic.lesson + 1);
  371         if (basic.lesson > 43)
  372         {
  373             if (basic.lesson > MAX_BASIC_LESSONS)
  374                 basic_set_lesson (MAX_BASIC_LESSONS);
  375             wg_label = GTK_LABEL (get_wg ("label_heading"));
  376             gtk_label_set_text (wg_label, _("Positions of keys seems to be learned!"));
  377             tmp_str = g_strdup (_(" Congratulations!\n"
  378                           " You have accomplished the entire basic course.\n"
  379                           " Go to the next type of exercise: adaptability.\n"
  380                           " There you will practice mainly the accuracy.\n"));
  381         }
  382         else
  383             tmp_str = g_strdup (_(" All right, now you got it!\n Go to the next lesson.\n"));
  384 
  385         basic_init_char_set ();
  386         if (basic.lesson != MAX_BASIC_LESSONS)
  387             basic.lesson_increased = TRUE;
  388     }
  389 
  390     wg = get_wg ("text_tutor");
  391     buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (wg));
  392     gtk_text_buffer_insert_at_cursor (buf, tmp_str, strlen (tmp_str));
  393     g_free (tmp_str);
  394 }