1 /*
2  * YASR ("Yet Another Screen Reader") is an attempt at a lightweight,
3  * portable screen reader.
4  *
5  * Copyright (C) 2001-2003 by Michael P. Gorse. All rights reserved.
6  *
7  * YASR comes with ABSOLUTELY NO WARRANTY.
8  *
9  * This is free software, placed under the terms of the
10  * GNU Lesser General Public License, as published by the Free Software
11  * Foundation.  Please see the file COPYING for details.
12  *
13  * Web Page: http://yasr.sf.net
14  *
15  * This software is maintained by:
16  * Michael P. Gorse <mgorse@users.sourceforge.net>
17  */
18 
19 #include "yasr.h"
20 
kb_add(Keymap * map,int k,int i,int na,int * a,int flag)21 int kb_add(Keymap * map, int k, int i, int na, int *a, int flag)
22 {
23   int v = 0;
24   Keybind *kp, *tmpk;
25 
26   if ((v = kb_search(map, k)) == -1)
27   {
28     v = map->numkeys;
29   }
30   kp = map->kb + v;
31   if (v < map->numkeys)
32   {
33     switch (flag)
34     {
35     case 0:
36       return (-1);		/* error */
37 
38     case 1:			/* add at the beginning */
39       tmpk = kp->next;
40       kp->next = malloc(sizeof(Keybind));
41       (void) memcpy(kp->next, kp, sizeof(Keybind));
42       kp->next->next = tmpk;
43       kp->index = i;
44       kp->argp = a;
45       kp->numargs = na;
46       return (0);
47 
48     case 2:			/* add after */
49       tmpk = kp;
50       while (tmpk->next)
51       {
52 	tmpk = tmpk->next;
53       }
54       tmpk->next = malloc(sizeof(Keybind));
55       tmpk = tmpk->next;
56       tmpk->key = k;
57       tmpk->index = i;
58       tmpk->argp = a;
59       tmpk->numargs = na;
60       return (0);
61     }
62   }
63   if (++(map->numkeys) % 32 == 1)
64   {
65     map->kb = realloc(map->kb, (map->numkeys + 31) * sizeof(Keybind));
66     kp = map->kb + v;
67   }
68   kp->key = k;
69   kp->index = i;
70   kp->argp = a;
71   kp->numargs = na;
72 
73   return (0);
74 }
75 
76 
kb_search(Keymap * map,int k)77 int kb_search(Keymap * map, int k)
78 {
79   int v;
80 
81   for (v = 0; v < map->numkeys; v++)
82   {
83     if (map->kb[v].key == k)
84     {
85       return v;
86     }
87   }
88 
89   return (-1);
90 }
91 
92 
93 #ifdef USE_KBWIZ
kb_del(Keymap * map,int key)94 void kb_del(Keymap * map, int key)
95 {
96   int v;
97   Keybind *kp, *tmpk;
98 
99   v = kb_search(map, key);
100   if (v == -1)
101   {
102     return;
103   }
104   kp = map->kb + v;
105   tmpk = kp;
106   while ((tmpk = tmpk->next) != NULL)
107   {
108     free(tmpk);
109   }
110   (void) memmove(kp, kp + 1, (map->numkeys - v - 1) * sizeof(Keybind));
111 }
112 #endif /*USE_KBWIZ */
113 
114 
kbwiz(int key)115  /*ARGSUSED*/ int kbwiz(int key)
116 {
117 #ifdef USE_KBWIZ
118   static int state = 0;
119   static Keymap *map;
120   static int sourcekey;
121   Keybind *kb;
122 
123   if (!key)
124   {				/* initialize */
125     if (ui.revmode)
126     {
127       map = &rev.keymap;
128       tts_say(_("Editing review keymap. Enter command."));
129     } else
130     {
131       map = &ui.keymap;
132       tts_say(_("Editing normal keymap. Enter command."));
133     }
134     return (1);
135   }
136 
137   switch (state)
138   {
139   case 0:
140     switch (key)
141     {
142     case 'c':
143     case 'C':
144       state = 1;
145       tts_say(_("Copy which key?"));
146       break;
147     case 'd':
148     case 'D':
149       state = 3;
150       tts_say(_("Delete which key?"));
151       break;
152     case 'm':
153     case 'M':
154       state = 5;
155       tts_say(_("Move which key?"));
156       break;
157     case 27:
158       tts_say(_("Exiting keyboard wizard."));
159       ui_funcman(0);
160       break;
161     default:
162       tts_say(_("c to copy, d to delete, m to move."));
163       break;
164     }
165     break;
166 
167   case 1:
168   case 3:
169   case 5:
170     if (key == 27)
171     {
172       state = 0;
173       tts_say(_("Command aborted."));
174       break;
175     }
176     if (kb_search(map, key) == -1)
177     {
178       tts_say(_("Key not defined."));
179       break;
180     }
181     if (state == 3)
182     {
183       kb_del(map, key);
184       state = 0;
185       tts_say(_("Key deleted."));
186     }
187     else
188     {
189       state++;
190       tts_say(_("To which key?"));
191       sourcekey = key;
192     }
193     break;
194   case 2:
195   case 6:
196     if (kb_search(map, key) != -1)
197     {
198       tts_say(_("Keystroke already defined. Aborting."));
199       state = 0;
200       break;
201     }
202     kb = map->kb + kb_search(map, sourcekey);
203     (void) kb_add(map, key, kb->index, kb->numargs, kb->argp, 0);
204     if (state == 6)
205     {
206       kb_del(map, sourcekey);
207       tts_say(_("key moved."));
208     }
209     else
210     {
211       tts_say(_("Key copied."));
212     }
213     state = 0;
214     break;
215   }
216   return (1);
217 }
218 #else
219   tts_say(_("Not available."));
220   ui_funcman(0);
221   return (1);
222 }
223 #endif
224