source: keybinding.c @ 315babf

release-1.10release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 315babf was e1b136bf, checked in by Nelson Elhage <nelhage@mit.edu>, 15 years ago
Fix handling of C-SPACE, etc. Instead of storing key sequences NULL-terminated, store an explicit length everywhere, so that we can handle C-SPACE (which is a 0).
  • Property mode set to 100644
File size: 3.4 KB
Line 
1#include <ctype.h>
2#include <string.h>
3#include "owl.h"
4
5static const char fileIdent[] = "$Id$";
6
7/*
8 * TODO: Idea for allowing functions to be user-specified ---
9 *      Have function have a context bitmask that says where it
10 *      can be used, and have keymaps also have one, and compare
11 *      the two when setting.
12 *     
13 */
14
15/* sets up a new keybinding for a command */
16int owl_keybinding_init(owl_keybinding *kb, char *keyseq, char *command, void (*function_fn)(void), char *desc)
17{
18  char **ktokens;
19  int    nktokens, i;
20 
21  owl_function_debugmsg("owl_keybinding_init: creating binding for <%s> with desc: <%s>", keyseq, desc);
22  if (command && !function_fn) {
23    kb->type = OWL_KEYBINDING_COMMAND;
24  } else if (!command && function_fn) {
25    kb->type = OWL_KEYBINDING_FUNCTION;
26  } else {
27    return(-1);
28  }
29
30  ktokens = atokenize(keyseq, " ", &nktokens);
31  if (!ktokens) return(-1);
32  if (nktokens > OWL_KEYMAP_MAXSTACK) {
33    atokenize_free(ktokens, nktokens);
34    return(-1);
35  }
36  kb->keys = owl_malloc(nktokens*sizeof(int));
37  for (i=0; i<nktokens; i++) {
38    kb->keys[i] = owl_keypress_fromstring(ktokens[i]);
39    if (kb->keys[i] == ERR) { 
40      atokenize_free(ktokens, nktokens);
41      owl_free(kb->keys);
42      return(-1);
43    }
44  }
45  kb->len = nktokens;
46
47  atokenize_free(ktokens, nktokens);
48
49  if (command) kb->command = owl_strdup(command);
50  kb->function_fn = function_fn;
51  if (desc) kb->desc = owl_strdup(desc);
52  else kb->desc = NULL;
53  return(0);
54}
55
56/* Releases data associated with a keybinding */
57void owl_keybinding_free(owl_keybinding *kb)
58{
59  if (kb->keys) owl_free(kb->keys);
60  if (kb->desc) owl_free(kb->desc);
61  if (kb->command) owl_free(kb->command);
62}
63
64/* Releases data associated with a keybinding, and the kb itself */
65void owl_keybinding_free_all(owl_keybinding *kb)
66{
67  owl_keybinding_free(kb);
68  owl_free(kb);
69}
70
71/* executes a keybinding */
72void owl_keybinding_execute(owl_keybinding *kb, int j)
73{
74  if (kb->type == OWL_KEYBINDING_COMMAND && kb->command) {
75    owl_function_command_norv(kb->command);
76  } else if (kb->type == OWL_KEYBINDING_FUNCTION && kb->function_fn) {
77    kb->function_fn();
78  }
79}
80
81/* returns 0 on success */
82int owl_keybinding_stack_tostring(int *j, int len, char *buff, int bufflen)
83{
84  char *pos = buff;
85  int   rem = bufflen;
86  int   i, n;
87
88  for (i=0; i < len; i++) {
89    owl_keypress_tostring(j[i], 0, pos, rem-1);
90    if (i < len - 1) strcat(pos, " ");
91    n = strlen(pos);
92    pos += n;
93    rem -= n;
94  }
95  return 0;
96}
97
98/* returns 0 on success */
99int owl_keybinding_tostring(owl_keybinding *kb, char *buff, int bufflen)
100{
101  return owl_keybinding_stack_tostring(kb->keys, kb->len, buff, bufflen);
102}
103
104char *owl_keybinding_get_desc(owl_keybinding *kb)
105{
106  return kb->desc;
107}
108
109/* returns 0 on no match, 1 on subset match, and 2 on complete match */
110int owl_keybinding_match(owl_keybinding *kb, owl_keyhandler *kh)
111{
112  int i;
113  for(i = 0; i <= kh->kpstackpos && i < kb->len; i++) {
114    if(kb->keys[i] != kh->kpstack[i])
115      return 0;
116  }
117
118  /* If we've made it to this point, then they match as far as they are. */
119  if(kb->len == kh->kpstackpos + 1) {
120    /* Equal length */
121    return 2;
122  } else if(kb->len > kh->kpstackpos + 1) {
123    return 1;
124  }
125
126  return 0;
127}
128
129/* returns 1 if keypress sequence is the same */
130int owl_keybinding_equal(owl_keybinding *kb1, owl_keybinding *kb2)
131{
132  int i;
133
134  if(kb1->len != kb2->len) return 0;
135
136  for(i = 0; i < kb1->len; i++) {
137    if(kb1->keys[i] != kb2->keys[i])
138      return 0;
139  }
140
141  return 1;
142}
Note: See TracBrowser for help on using the repository browser.