home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / file / managers / mc-3.2 / mc-3 / mc-3.2.1 / src / learn.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-17  |  8.1 KB  |  308 lines

  1. /* Learn keys
  2.    Copyright (C) 1995 The Free Software Foundation
  3.    
  4.    Written by: 1995 Jakub Jelinek
  5.  
  6.    This program is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2 of the License, or
  9.    (at your option) any later version.
  10.  
  11.    This program is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with this program; if not, write to the Free Software
  18.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
  19.  */
  20.  
  21. #include <config.h>
  22. #ifdef HAVE_UNISTD_H
  23. #   include <unistd.h>
  24. #endif
  25. #include <string.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>        /* For malloc() */
  28. #include <sys/types.h>
  29. #include <sys/param.h>
  30. #include <sys/stat.h>
  31. #include "tty.h"
  32. #include "mad.h"
  33. #include "util.h"    /* Needed for the externs and convert_controls */
  34. #include "win.h"
  35. #include "color.h"
  36. #include "dlg.h"
  37. #include "widget.h"
  38. #include "dialog.h"        /* For do_refresh() */
  39. #include "profile.h"        /* Save profile */
  40. #include "key.h"
  41. #include "setup.h"
  42. #include "main.h"
  43. #define UX        3
  44. #define UY        3
  45.  
  46. #define BX        25
  47. #define BY        UY + 17
  48.  
  49. #define ROWS        13
  50. #define COLSHIFT    23
  51.  
  52. #define BUTTONS     2
  53.  
  54. struct {
  55.     int ret_cmd, y, x;
  56.     char *text;
  57.     int hkey, hpos;
  58. } learn_but[BUTTONS] = {
  59.     { B_CANCEL, 0, 14, "[ Cancel ]",  'c', 2, },
  60.     { B_ENTER,  0,  0, "[[ Save ]]", 's', 3, },
  61. };
  62.  
  63. static Dlg_head *learn_dlg;
  64. typedef struct {
  65.     Widget *button;
  66.     Widget *label;
  67.     int ok;
  68.     char *sequence;
  69. } learnkey;
  70. static learnkey *learnkeys = NULL;
  71. static int learn_total;
  72. static int learnok;
  73. static int learnchanged;
  74.  
  75. #ifndef HAVE_X
  76. static void learn_refresh (void)
  77. {
  78.     attrset (REVERSE_COLOR);
  79.     dlg_erase (learn_dlg);
  80.     
  81.     draw_box (learn_dlg, 1, 2, 21, 70);
  82.     
  83.     attrset (COLOR_HOT_NORMAL);
  84.     dlg_move (learn_dlg, 1, (72 - 19) / 2);
  85.     addstr (" Learn keys ");
  86. }
  87. #endif
  88.  
  89. static int learn_button (int action, void *param)
  90. {
  91.     char *seq;
  92.     Dlg_head *d = message (D_INSERT | 1, " Teach me a key ",
  93. "Please press the %s\n"
  94. "and then wait until this message disappears.\n\n"
  95. "Then, press it again to see if OK appears\n"
  96. "next to its button.\n\n"
  97. "If you want to escape, press a single Escape key\n"
  98. "and wait as well.", 
  99.         key_name_conv_tab [action - B_USER].longname);
  100.     refresh ();
  101.     if (learnkeys [action - B_USER].sequence != NULL)
  102.         free (learnkeys [action - B_USER].sequence);
  103.     seq = learn_key ();
  104.  
  105.     if (seq){
  106.     /* Esc hides the dialog and do not allow definitions of
  107.      * regular characters
  108.      */
  109.     if (*seq && strcmp (seq, "\\e") && strcmp (seq, "\\e\\e")
  110.         && (seq [1] || (*seq < ' ' && *seq > '~'))){
  111.         
  112.         learnchanged = 1;
  113.         learnkeys [action - B_USER].sequence = seq;
  114.         seq = convert_controls (seq);
  115.         define_sequence (key_name_conv_tab [action - B_USER].code, seq, 
  116.                  MCKEY_NOACTION);
  117.     }
  118.     
  119.         free (seq);
  120.     }
  121.     
  122.     dlg_run_done (d);
  123.     destroy_dlg (d);
  124.     dlg_select_widget (learn_dlg, learnkeys [action - B_USER].button);
  125.     return 0; /* Do not kill learn_dlg */
  126. }
  127.  
  128. static int learn_move (int right)
  129. {
  130.     int i, totalcols;
  131.     
  132.     totalcols = (learn_total - 1) / ROWS + 1;
  133.     for (i = 0; i < learn_total; i++)
  134.         if (learnkeys [i].button == learn_dlg->current->widget) {
  135.             if (right) {
  136.                 if (i < learn_total - ROWS)
  137.                     i += ROWS;
  138.                 else 
  139.                     i %= ROWS;
  140.             } else {
  141.                 if (i / ROWS)
  142.                     i -= ROWS;
  143.                 else if (i + (totalcols - 1) * ROWS >= learn_total)
  144.                     i += (totalcols - 2) * ROWS;
  145.                 else
  146.                     i += (totalcols - 1) * ROWS;
  147.             }
  148.             dlg_select_widget (learn_dlg, (void *) learnkeys [i].button);
  149.             return 1;
  150.         }
  151.     return 0;
  152. }
  153.  
  154. static int learn_check_key (int c)
  155. {
  156.     int i;
  157.  
  158.     for (i = 0; i < learn_total; i++) {
  159.         if (key_name_conv_tab [i].code == c) {
  160.         if (!learnkeys [i].ok) {
  161.             dlg_select_widget (learn_dlg, learnkeys [i].button);
  162.             label_set_text ((WLabel *) learnkeys [i].label,
  163.                 "OK");
  164.             learnkeys [i].ok = 1;
  165.             learnok++;
  166.             if (learnok >= learn_total) {
  167.                 learn_dlg->ret_value = B_CANCEL;
  168.                 if (learnchanged) {
  169.                     if (query_dialog (" Learn keys ", "\
  170. It seems that all your keys already\n\
  171. work fine. That's great.",
  172.                         1, 2, " Save ", " Discard ") == 0)
  173.                         learn_dlg->ret_value = B_ENTER;
  174.                 } else {
  175.                     message (1, " Learn keys ", "\
  176. Great! You have a complete terminal database!\n\
  177. All your keys work well.");
  178.                 }
  179.                 learn_dlg->running = 0;
  180.             }
  181.             return 1;
  182.         }
  183.         }
  184.     }
  185.     switch (c) {
  186.         case KEY_LEFT:
  187.         case 'h':
  188.             return learn_move (0);
  189.         case KEY_RIGHT:
  190.         case 'l':
  191.             return learn_move (1);
  192.         case 'j':
  193.             dlg_one_down (learn_dlg);
  194.             return 1;
  195.         case 'k':
  196.             dlg_one_up (learn_dlg);
  197.             return 1;
  198.         case 's':
  199.         case 'S':
  200.         case 'c':
  201.         case 'C':
  202.             /* Prevent from disappearing if a non-defined sequence is pressed
  203.                and contains s or c. Use ALT('s') or ALT('c'). */
  204.             return 1;
  205.     }    
  206.     return 0;
  207. }
  208.  
  209. static int learn_callback (Dlg_head * h, int Par, int Msg)
  210. {
  211.     switch (Msg) {
  212.     case DLG_DRAW:
  213.     learn_refresh ();
  214.     break;
  215.     case DLG_KEY:
  216.         return learn_check_key (Par);
  217.     }
  218.     return 0;
  219. }
  220.  
  221. static void init_learn (void)
  222. {
  223.     int x, y, i, j;
  224.     key_code_name_t *key;
  225.     char buffer [22];
  226.  
  227.     do_refresh ();
  228.  
  229.     learn_dlg = create_dlg (0, 0, 23, 75, dialog_colors,
  230.                   learn_callback, "[Learn keys]", "Learn keys",
  231.                   DLG_CENTER);
  232.     x_set_dialog_title (learn_dlg, "Learn keys");
  233.  
  234. #define XTRACT(i) BY+learn_but[i].y, BX+learn_but[i].x, learn_but[i].ret_cmd, learn_but[i].text, learn_but[i].hkey, learn_but[i].hpos, 0, 0
  235.  
  236.     for (i = 0; i < BUTTONS; i++)
  237.     add_widget (learn_dlg, button_new (XTRACT (i)));
  238.     
  239.     x = UX;
  240.     y = UY;
  241.     for (key = key_name_conv_tab, j = 0; key->name != NULL &&
  242.         strcmp (key->name, "kpleft"); key++, j++);
  243.     learnkeys = (learnkey *) xmalloc (sizeof (learnkey) * j, "Learn keys");
  244.     x += ((j - 1) / ROWS) * COLSHIFT;
  245.     y += (j - 1) % ROWS;
  246.     learn_total = j;
  247.     learnok = 0;
  248.     learnchanged = 0;
  249.     for (i = j - 1, key = key_name_conv_tab + j - 1; i >= 0; i--, key--) {
  250.         learnkeys [i].ok = 0;
  251.         learnkeys [i].sequence = NULL;
  252.         sprintf (buffer, " %-18s", key->longname);
  253.     add_widget (learn_dlg, learnkeys [i].button = (Widget *)
  254.         button_new (y, x, B_USER + i, buffer, 0, -1, learn_button, 0));
  255.     add_widget (learn_dlg, learnkeys [i].label = (Widget *)
  256.         label_new (y, x + 20, ""));
  257.     if (i % 13)
  258.         y--;
  259.     else {
  260.         x -= COLSHIFT;
  261.         y = UY + ROWS - 1;
  262.     }
  263.     }
  264.     add_widget (learn_dlg, label_new (UY+14, 5, "Press all the keys mentioned here. After you have done it, check"));
  265.     add_widget (learn_dlg, label_new (UY+15, 5, "which keys are not marked with OK.  Press space on the missing"));
  266.     add_widget (learn_dlg, label_new (UY+16, 5, "key, or click with the mouse to define it. Move around with Tab."));
  267. }
  268.  
  269. static void learn_done (void)
  270. {
  271.     destroy_dlg (learn_dlg);
  272.     repaint_screen ();
  273. }
  274.  
  275. void learn_save (void)
  276. {
  277.     int i;
  278.     char *section = copy_strings ("terminal:", getenv ("TERM"), NULL);
  279.  
  280.     for (i = 0; i < learn_total; i++) {
  281.     if (learnkeys [i].sequence != NULL) {
  282.         WritePrivateProfileString (section, key_name_conv_tab [i].name,
  283.             learnkeys [i].sequence, profile_name);
  284.         }
  285.     }
  286. }
  287.  
  288. void learn_keys (void)
  289. {
  290.     int save_old_esc_mode = old_esc_mode;
  291.     
  292.     old_esc_mode = 0; /* old_esc_mode cannot work in learn keys dialog */
  293.     init_learn ();
  294.  
  295.     run_dlg (learn_dlg);
  296.     
  297.     old_esc_mode = save_old_esc_mode;
  298.     
  299.     switch (learn_dlg->ret_value) {
  300.     case B_ENTER:
  301.         learn_save ();
  302.         break;
  303.     }
  304.  
  305.     learn_done ();
  306. }
  307.  
  308.