1 /*
2 * ui_keypad.c
3 *
4 * MontaVista IPMI code, a simple curses UI keypad handler
5 *
6 * Author: MontaVista Software, Inc.
7 * Corey Minyard <minyard@mvista.com>
8 * source@mvista.com
9 *
10 * Copyright 2002,2003 MontaVista Software Inc.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2 of
15 * the License, or (at your option) any later version.
16 *
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
26 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
27 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * You should have received a copy of the GNU Lesser General Public
30 * License along with this program; if not, write to the Free
31 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 */
33
34
35 #include <errno.h>
36 #include <string.h>
37 #include "ui_keypad.h"
38
39 #include <OpenIPMI/internal/ilist.h>
40 #include <OpenIPMI/internal/ipmi_malloc.h>
41
search_key(void * item,void * cb_data)42 static int search_key(void *item, void *cb_data)
43 {
44 struct key_entry *entry = item;
45 int *val = cb_data;
46
47 return (entry->key == *val);
48 }
49
50 static struct key_entry *
find_key(ilist_iter_t * iter,keypad_t keypad,int key)51 find_key(ilist_iter_t *iter, keypad_t keypad, int key)
52 {
53 int hash = ((unsigned int) key) % NUM_KEY_ENTRIES;
54 struct key_entry *entry;
55
56 ilist_init_iter(iter, keypad->keys[hash]);
57 ilist_unpositioned(iter);
58 entry = ilist_search_iter(iter, search_key, &key);
59 return entry;
60 }
61
62 int
keypad_handle_key(keypad_t keypad,int key,void * cb_data)63 keypad_handle_key(keypad_t keypad, int key, void *cb_data)
64 {
65 ilist_iter_t iter;
66 struct key_entry *entry;
67
68 entry = find_key(&iter, keypad, key);
69 if (!entry)
70 return ENOENT;
71
72 return entry->handler(key, cb_data);
73 }
74
75 int
keypad_bind_key(keypad_t keypad,int key,key_handler_t handler)76 keypad_bind_key(keypad_t keypad, int key, key_handler_t handler)
77 {
78 int hash = ((unsigned int) key) % NUM_KEY_ENTRIES;
79 ilist_iter_t iter;
80 struct key_entry *entry;
81
82 if (find_key(&iter, keypad, key))
83 return EEXIST;
84
85 entry = ipmi_mem_alloc(sizeof(*entry));
86 if (!entry)
87 return ENOMEM;
88
89 entry->key = key;
90 entry->handler = handler;
91 if (!ilist_add_tail(keypad->keys[hash], entry, NULL)) {
92 ipmi_mem_free(entry);
93 return ENOMEM;
94 }
95
96 return 0;
97 }
98
99 int
keypad_unbind_key(keypad_t keypad,int key)100 keypad_unbind_key(keypad_t keypad, int key)
101 {
102 ilist_iter_t iter;
103 struct key_entry *entry;
104
105 entry = find_key(&iter, keypad, key);
106 if (!entry)
107 return ENOENT;
108
109 ilist_delete(&iter);
110 ipmi_mem_free(entry);
111 return 0;
112 }
113
114 static void
del_key_entry(ilist_iter_t * iter,void * item,void * cb_data)115 del_key_entry(ilist_iter_t *iter, void *item, void *cb_data)
116 {
117 ilist_delete(iter);
118 ipmi_mem_free(item);
119 }
120
121 void
keypad_free(keypad_t keypad)122 keypad_free(keypad_t keypad)
123 {
124 int i;
125
126 for (i=0; i<NUM_KEY_ENTRIES; i++) {
127 if (keypad->keys[i]) {
128 ilist_iter(keypad->keys[i], del_key_entry, NULL);
129 free_ilist(keypad->keys[i]);
130 }
131 }
132 ipmi_mem_free(keypad);
133 }
134
135 keypad_t
keypad_alloc(void)136 keypad_alloc(void)
137 {
138 keypad_t nv = ipmi_mem_alloc(sizeof(*nv));
139 int i;
140
141 if (nv) {
142 memset(nv, 0, sizeof(*nv));
143 for (i=0; i<NUM_KEY_ENTRIES; i++) {
144 nv->keys[i] = alloc_ilist();
145 if (!nv->keys[i])
146 goto out_err;
147 }
148 }
149
150 return nv;
151
152 out_err:
153 keypad_free(nv);
154 return NULL;
155 }
156
157