1 /* $NetBSD: item.c,v 1.12 2012/03/21 05:33:27 matt Exp $ */
4 * Copyright (c) 1998-1999 Brett Lymn (blymn@baea.com.au, brett_lymn@yahoo.com.au)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.12 2012/03/21 05:33:27 matt Exp $");
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
62 item_visible(ITEM
*item
)
65 return E_BAD_ARGUMENT
;
66 if (item
->parent
== NULL
)
67 return E_NOT_CONNECTED
;
73 * Return the pointer to the item name
81 return item
->name
.string
;
85 * Return the pointer to the item description
88 item_description(ITEM
*item
)
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
)
104 _menui_default_menu
.item_init
= func
;
106 menu
->item_init
= func
;
112 * Return a pointer to the item initialisation routine.
115 item_init(MENU
*menu
)
118 return _menui_default_menu
.item_init
;
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
)
131 _menui_default_menu
.item_term
= func
;
133 menu
->item_term
= func
;
138 * Return a pointer to the termination function
141 item_term(MENU
*menu
)
144 return _menui_default_menu
.item_term
;
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
155 item_selected(MENU
*menu
, int **sel
)
160 return E_BAD_ARGUMENT
;
163 for (i
= 0, j
= 0; i
< menu
->item_count
; i
++)
164 if (menu
->items
[i
]->selected
)
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
)
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
188 set_item_opts(ITEM
*item
, OPTIONS opts
)
190 /* selectable seems to be the only allowable item opt! */
191 if (opts
!= O_SELECTABLE
)
192 return E_SYSTEM_ERROR
;
195 _menui_default_item
.opts
= opts
;
202 * Set item options on.
205 item_opts_on(ITEM
*item
, OPTIONS opts
)
207 if (opts
!= O_SELECTABLE
)
208 return E_SYSTEM_ERROR
;
211 _menui_default_item
.opts
|= opts
;
218 * Turn off the named options.
221 item_opts_off(ITEM
*item
, OPTIONS opts
)
223 if (opts
!= O_SELECTABLE
)
224 return E_SYSTEM_ERROR
;
227 _menui_default_item
.opts
&= ~(opts
);
229 item
->opts
&= ~(opts
);
234 * Return the current options set in item.
237 item_opts(ITEM
*item
)
240 return _menui_default_item
.opts
;
246 * Set the selected flag of the item iff the menu options allow it.
249 set_item_value(ITEM
*param_item
, int flag
)
251 ITEM
*item
= (param_item
!= NULL
) ? param_item
: &_menui_default_item
;
253 /* not bound to a menu */
254 if (item
->parent
== NULL
)
255 return E_NOT_CONNECTED
;
257 /* menu options do not allow multi-selection */
258 if ((item
->parent
->opts
& O_ONEVALUE
) == O_ONEVALUE
)
259 return E_REQUEST_DENIED
;
261 item
->selected
= flag
;
262 _menui_draw_item(item
->parent
, item
->index
);
267 * Return the item value of the item.
270 item_value(ITEM
*item
)
273 return _menui_default_item
.selected
;
275 return item
->selected
;
279 * Allocate a new item and return the pointer to the newly allocated
283 new_item(char *name
, char *description
)
290 /* allocate a new item structure for ourselves */
291 if ((new_one
= (ITEM
*)malloc(sizeof(ITEM
))) == NULL
)
294 /* copy in the defaults for the item */
295 (void)memcpy(new_one
, &_menui_default_item
, sizeof(ITEM
));
297 /* fill in the name structure - first the length and then
298 allocate room for the string & copy that. */
299 new_one
->name
.length
= strlen(name
);
300 if ((new_one
->name
.string
= (char *)
301 malloc(sizeof(char) * new_one
->name
.length
+ 1)) == NULL
) {
302 /* uh oh malloc failed - clean up & exit */
307 strcpy(new_one
->name
.string
, name
);
309 if (description
== NULL
)
310 new_one
->description
.length
= 0;
312 /* fill in the description structure, stash the length then
313 allocate room for description string and copy it in */
314 new_one
->description
.length
= strlen(description
);
315 if ((new_one
->description
.string
=
316 (char *) malloc(sizeof(char) *
317 new_one
->description
.length
+ 1)) == NULL
) {
320 * - free up allocated memory and return
322 free(new_one
->name
.string
);
327 strcpy(new_one
->description
.string
, description
);
334 * Free the allocated storage associated with item.
337 free_item(ITEM
*item
)
340 return E_BAD_ARGUMENT
;
342 /* check for connection to menu */
343 if (item
->parent
!= NULL
)
346 /* no connections, so free storage starting with the strings */
347 free(item
->name
.string
);
348 if (item
->description
.length
)
349 free(item
->description
.string
);
355 * Set the menu's current item to the one given.
358 set_current_item(MENU
*param_menu
, ITEM
*item
)
360 MENU
*menu
= (param_menu
!= NULL
) ? param_menu
: &_menui_default_menu
;
363 /* check if we have been called from an init type function */
364 if (menu
->in_init
== 1)
367 /* check we have items in the menu */
368 if (menu
->items
== NULL
)
369 return E_NOT_CONNECTED
;
371 if ((i
= item_index(item
)) < 0)
372 /* item must not be a part of this menu */
373 return E_BAD_ARGUMENT
;
380 * Return a pointer to the current item for the menu
383 current_item(MENU
*menu
)
388 if (menu
->items
== NULL
)
391 return menu
->items
[menu
->cur_item
];
395 * Return the index into the item array that matches item.
398 item_index(ITEM
*item
)
401 return _menui_default_item
.index
;