Sync usage with man page.
[netbsd-mini2440.git] / lib / libmenu / item.c
blob6e14efd040f4f3139d76f5f496ba21e070a27fab
1 /* $NetBSD: item.c,v 1.10 2003/09/29 12:32:24 blymn Exp $ */
3 /*-
4 * Copyright (c) 1998-1999 Brett Lymn (blymn@baea.com.au, brett_lymn@yahoo.com.au)
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include <sys/cdefs.h>
30 __RCSID("$NetBSD: item.c,v 1.10 2003/09/29 12:32:24 blymn Exp $");
32 #include <menu.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include "internals.h"
37 /* the following is defined in menu.c - it is the default menu struct */
38 extern MENU _menui_default_menu;
40 /* keep default item options for setting in new_item */
41 ITEM _menui_default_item = {
42 {NULL, 0}, /* item name struct */
43 {NULL, 0}, /* item description struct */
44 NULL, /* user pointer */
45 0, /* is item visible? */
46 0, /* is item selected? */
47 0, /* row item is on */
48 0, /* column item is on */
49 O_SELECTABLE, /* item options */
50 NULL, /* parent menu item is bound to */
51 -1, /* index number if item attached to a menu */
52 NULL, /* left neighbour */
53 NULL, /* right neighbour */
54 NULL, /* up neighbour */
55 NULL /* down neighbour */
59 * Return the item visibility flag
61 int
62 item_visible(ITEM *item)
64 if (item == NULL)
65 return E_BAD_ARGUMENT;
66 if (item->parent == NULL)
67 return E_NOT_CONNECTED;
69 return item->visible;
73 * Return the pointer to the item name
75 char *
76 item_name(ITEM *item)
78 if (item == NULL)
79 return NULL;
81 return item->name.string;
85 * Return the pointer to the item description
87 char *
88 item_description(ITEM *item)
90 if (item == NULL)
91 return NULL;
93 return item->description.string;
97 * Set the application defined function called when the menu is posted or
98 * just after the current item changes.
101 set_item_init(MENU *menu, Menu_Hook func)
103 if (menu == NULL)
104 _menui_default_menu.item_init = func;
105 else
106 menu->item_init = func;
107 return E_OK;
112 * Return a pointer to the item initialisation routine.
114 Menu_Hook
115 item_init(MENU *menu)
117 if (menu == NULL)
118 return _menui_default_menu.item_init;
119 else
120 return menu->item_init;
124 * Set the user defined function to be called when menu is unposted or just
125 * before the current item changes.
128 set_item_term(MENU *menu, Menu_Hook func)
130 if (menu == NULL)
131 _menui_default_menu.item_term = func;
132 else
133 menu->item_term = func;
134 return E_OK;
138 * Return a pointer to the termination function
140 Menu_Hook
141 item_term(MENU *menu)
143 if (menu == NULL)
144 return _menui_default_menu.item_term;
145 else
146 return menu->item_term;
150 * Returns the number of items that are selected.
151 * The index numbers of the items are placed in the dynamically allocated
152 * int array *sel.
155 item_selected(MENU *menu, int **sel)
157 int i, j;
159 if (menu == NULL)
160 return E_BAD_ARGUMENT;
162 /* count selected */
163 for (i = 0, j = 0; i < menu->item_count; i++)
164 if (menu->items[i]->selected)
165 j++;
167 if (j == 0) {
168 *sel = NULL;
169 return 0;
172 if ( (*sel = malloc(sizeof(int) * j)) == NULL)
173 return E_SYSTEM_ERROR;
175 for (i = 0, j = 0; i < menu->item_count; i++)
176 if (menu->items[i]->selected)
177 (*sel)[j++] = i;
179 return j;
183 * Set the item options. We keep a global copy of the current item options
184 * as subsequent new_item calls will use the updated options as their
185 * defaults.
188 set_item_opts(item, opts)
189 ITEM *item;
190 OPTIONS opts;
192 /* selectable seems to be the only allowable item opt! */
193 if (opts != O_SELECTABLE)
194 return E_SYSTEM_ERROR;
196 if (item == NULL)
197 _menui_default_item.opts = opts;
198 else
199 item->opts = opts;
200 return E_OK;
204 * Set item options on.
207 item_opts_on(ITEM *item, OPTIONS opts)
209 if (opts != O_SELECTABLE)
210 return E_SYSTEM_ERROR;
212 if (item == NULL)
213 _menui_default_item.opts |= opts;
214 else
215 item->opts |= opts;
216 return E_OK;
220 * Turn off the named options.
223 item_opts_off(ITEM *item, OPTIONS opts)
225 if (opts != O_SELECTABLE)
226 return E_SYSTEM_ERROR;
228 if (item == NULL)
229 _menui_default_item.opts &= ~(opts);
230 else
231 item->opts &= ~(opts);
232 return E_OK;
236 * Return the current options set in item.
238 OPTIONS
239 item_opts(ITEM *item)
241 if (item == NULL)
242 return _menui_default_item.opts;
243 else
244 return item->opts;
248 * Set the selected flag of the item iff the menu options allow it.
251 set_item_value(ITEM *param_item, int flag)
253 ITEM *item = (param_item != NULL) ? param_item : &_menui_default_item;
255 /* not bound to a menu */
256 if (item->parent == NULL)
257 return E_NOT_CONNECTED;
259 /* menu options do not allow multi-selection */
260 if ((item->parent->opts & O_ONEVALUE) == O_ONEVALUE)
261 return E_REQUEST_DENIED;
263 item->selected = flag;
264 _menui_draw_item(item->parent, item->index);
265 return E_OK;
269 * Return the item value of the item.
272 item_value(ITEM *item)
274 if (item == NULL)
275 return _menui_default_item.selected;
276 else
277 return item->selected;
281 * Allocate a new item and return the pointer to the newly allocated
282 * structure.
284 ITEM *
285 new_item(char *name, char *description)
287 ITEM *new_one;
289 if (name == NULL)
290 return NULL;
292 /* allocate a new item structure for ourselves */
293 if ((new_one = (ITEM *)malloc(sizeof(ITEM))) == NULL)
294 return NULL;
296 /* copy in the defaults for the item */
297 (void)memcpy(new_one, &_menui_default_item, sizeof(ITEM));
299 /* fill in the name structure - first the length and then
300 allocate room for the string & copy that. */
301 new_one->name.length = strlen(name);
302 if ((new_one->name.string = (char *)
303 malloc(sizeof(char) * new_one->name.length + 1)) == NULL) {
304 /* uh oh malloc failed - clean up & exit */
305 free(new_one);
306 return NULL;
309 strcpy(new_one->name.string, name);
311 if (description == NULL)
312 new_one->description.length = 0;
313 else {
314 /* fill in the description structure, stash the length then
315 allocate room for description string and copy it in */
316 new_one->description.length = strlen(description);
317 if ((new_one->description.string =
318 (char *) malloc(sizeof(char) *
319 new_one->description.length + 1)) == NULL) {
321 * malloc has failed
322 * - free up allocated memory and return
324 free(new_one->name.string);
325 free(new_one);
326 return NULL;
329 strcpy(new_one->description.string, description);
332 return new_one;
336 * Free the allocated storage associated with item.
339 free_item(ITEM *item)
341 if (item == NULL)
342 return E_BAD_ARGUMENT;
344 /* check for connection to menu */
345 if (item->parent != NULL)
346 return E_CONNECTED;
348 /* no connections, so free storage starting with the strings */
349 free(item->name.string);
350 if (item->description.length)
351 free(item->description.string);
352 free(item);
353 return E_OK;
357 * Set the menu's current item to the one given.
360 set_current_item(MENU *param_menu, ITEM *item)
362 MENU *menu = (param_menu != NULL) ? param_menu : &_menui_default_menu;
363 int i = 0;
365 /* check if we have been called from an init type function */
366 if (menu->in_init == 1)
367 return E_BAD_STATE;
369 /* check we have items in the menu */
370 if (menu->items == NULL)
371 return E_NOT_CONNECTED;
373 if ((i = item_index(item)) < 0)
374 /* item must not be a part of this menu */
375 return E_BAD_ARGUMENT;
377 menu->cur_item = i;
378 return E_OK;
382 * Return a pointer to the current item for the menu
384 ITEM *
385 current_item(MENU *menu)
387 if (menu == NULL)
388 return NULL;
390 if (menu->items == NULL)
391 return NULL;
393 return menu->items[menu->cur_item];
397 * Return the index into the item array that matches item.
400 item_index(ITEM *item)
402 if (item == NULL)
403 return _menui_default_item.index;
404 else
405 return item->index;