home · contact · privacy
Applied new formatting and documentation requirements to keybindings library.
[plomrogue] / src / keybindings.c
1 /* keybindings.c */
2
3
4
5 #include "keybindings.h"
6 #include <stdlib.h>  /* for malloc(), free(), atoi() */
7 #include <stdint.h>  /* for uint16_t */
8 #include <ncurses.h> /* for keycode defines in get_keyname() */
9 #include <string.h>  /* for strchr(), strlen(), strcmp(), memcpy()*/
10 #include "windows.h" /* for draw_all_wins() and WinMeta struct */
11 #include "misc.h"    /* for texfile_sizes() */
12 #include "main.h"    /* for World struct */
13
14
15
16 extern void init_keybindings(struct World * world)
17 {
18     FILE * file = fopen("keybindings", "r");
19     uint16_t lines, linemax;
20     textfile_sizes(file, &linemax, &lines);
21     struct KeyBinding * keybindings = malloc(lines * sizeof(struct KeyBinding));
22     char * command = malloc(linemax);
23     uint16_t commcount = 0;
24     char * cmdptr;
25     while (fgets(command, linemax, file))
26     {
27         keybindings[commcount].key = atoi(command);
28         cmdptr = strchr(command, ' ') + 1;
29         keybindings[commcount].name = malloc(strlen(cmdptr));
30         memcpy(keybindings[commcount].name, cmdptr, strlen(cmdptr) - 1);
31         keybindings[commcount].name[strlen(cmdptr) - 1] = '\0';
32         commcount++;
33     }
34     free(command);
35     fclose(file);
36     struct KeysWinData * keyswindata = malloc(sizeof(struct KeysWinData));
37     keyswindata->max = lines - 1;
38     keyswindata->select = 0;
39     keyswindata->edit = 0;
40     world->keybindings = keybindings;
41     world->keyswindata = keyswindata;
42 }
43
44
45
46 extern void save_keybindings(struct World * world)
47 {
48     struct KeysWinData * keyswindata = (struct KeysWinData *)
49                                        world->keyswindata;
50     struct KeyBinding * keybindings = world->keybindings;
51     FILE * file = fopen("keybindings", "w");
52     uint16_t linemax = 0;
53     uint16_t i;
54     for (i = 0; i <= keyswindata->max; i++)
55     {
56         if (strlen(keybindings[i].name) > linemax)
57         {
58             linemax = strlen(keybindings[i].name);
59         }
60     }
61     linemax = linemax + 6;         /* + 6 = + 3 digits + whitespace + \n + \0 */
62     char * line = malloc(linemax);
63     for (i = 0; i <= keyswindata->max; i++)
64     {
65         snprintf(line, linemax,
66                  "%d %s\n", keybindings[i].key, keybindings[i].name);
67         fwrite(line, sizeof(char), strlen(line), file);
68     }
69     free(line);
70     fclose(file);
71 }
72
73
74
75 extern uint16_t get_action_key(struct KeyBinding * keybindings, char * name)
76 {
77     uint16_t i = 0;
78     while (strcmp(keybindings[i].name, name) )
79     {
80         i++;
81     }
82     return keybindings[i].key;
83 }
84
85
86
87 extern char * get_keyname(uint16_t keycode)
88 {
89     char * keyname;
90     keyname = malloc(15);
91     if (32 < keycode && keycode < 127)
92     {
93         sprintf(keyname, "%c", keycode);
94     }
95     else if (keycode == 9)              /* TODO: Find a way more elegant than */
96     {                                   /*       hardcoding all of this?      */
97         sprintf(keyname, "TAB");
98     }
99     else if (keycode == 10)
100     {
101         sprintf(keyname, "RETURN");
102     }
103     else if (keycode == 27)
104     {
105         sprintf(keyname, "ESCAPE");
106     }
107     else if (keycode == 32)
108     {
109         sprintf(keyname, "SPACE");
110     }
111     else if (keycode == KEY_UP)
112     {
113         sprintf(keyname, "UP");
114     }
115     else if (keycode == KEY_DOWN)
116     {
117         sprintf(keyname, "DOWN");
118     }
119     else if (keycode == KEY_LEFT)
120     {
121         sprintf(keyname, "LEFT");
122     }
123     else if (keycode == KEY_RIGHT)
124     {
125         sprintf(keyname, "RIGHT");
126     }
127     else if (keycode == KEY_HOME)
128     {
129         sprintf(keyname, "HOME");
130     }
131     else if (keycode == KEY_BACKSPACE)
132     {
133         sprintf(keyname, "BACKSPACE");
134     }
135     else if (keycode >= KEY_F0 && keycode <= KEY_F(63))
136     {
137         uint16_t f = keycode - KEY_F0;
138         sprintf(keyname, "F%d", f);
139     }
140     else if (keycode == KEY_DC)
141     {
142         sprintf(keyname, "DELETE");
143     }
144     else if (keycode == KEY_IC)
145     {
146         sprintf(keyname, "INSERT");
147     }
148     else if (keycode == KEY_NPAGE)
149     {
150         sprintf(keyname, "NEXT PAGE");
151     }
152     else if (keycode == KEY_PPAGE)
153     {
154         sprintf(keyname, "PREV PAGE");
155     }
156     else if (keycode == KEY_END)
157     {
158         sprintf(keyname, "END");
159     }
160     else
161     {
162         sprintf(keyname, "(unknown)");
163     }
164     return keyname;
165 }
166
167
168
169 extern void keyswin_mod_key(struct World * world, struct WinMeta * win_meta)
170 {
171     world->keyswindata->edit = 1;
172     draw_all_wins (win_meta);
173     int key = getch();
174     if (key < 1000)
175     {
176         world->keybindings[world->keyswindata->select].key = key;
177     }
178     world->keyswindata->edit = 0;
179 }
180
181
182
183 extern void keyswin_move_selection(struct World * world, char dir)
184 {
185     if      ('u' == dir && world->keyswindata->select > 0)
186     {
187         world->keyswindata->select--;
188     }
189     else if ('d' == dir && world->keyswindata->select < world->keyswindata->max)
190     {
191         world->keyswindata->select++;
192     }
193 }