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