1 /* $NetBSD: item.c,v 1.10 2003/09/29 12:32:24 blymn 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.10 2003/09/29 12:32:24 blymn 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
, opts
)
192 /* selectable seems to be the only allowable item opt! */
193 if (opts
!= O_SELECTABLE
)
194 return E_SYSTEM_ERROR
;
197 _menui_default_item
.opts
= opts
;
204 * Set item options on.
207 item_opts_on(ITEM
*item
, OPTIONS opts
)
209 if (opts
!= O_SELECTABLE
)
210 return E_SYSTEM_ERROR
;
213 _menui_default_item
.opts
|= opts
;
220 * Turn off the named options.
223 item_opts_off(ITEM
*item
, OPTIONS opts
)
225 if (opts
!= O_SELECTABLE
)
226 return E_SYSTEM_ERROR
;
229 _menui_default_item
.opts
&= ~(opts
);
231 item
->opts
&= ~(opts
);
236 * Return the current options set in item.
239 item_opts(ITEM
*item
)
242 return _menui_default_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
);
269 * Return the item value of the item.
272 item_value(ITEM
*item
)
275 return _menui_default_item
.selected
;
277 return item
->selected
;
281 * Allocate a new item and return the pointer to the newly allocated
285 new_item(char *name
, char *description
)
292 /* allocate a new item structure for ourselves */
293 if ((new_one
= (ITEM
*)malloc(sizeof(ITEM
))) == 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 */
309 strcpy(new_one
->name
.string
, name
);
311 if (description
== NULL
)
312 new_one
->description
.length
= 0;
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
) {
322 * - free up allocated memory and return
324 free(new_one
->name
.string
);
329 strcpy(new_one
->description
.string
, description
);
336 * Free the allocated storage associated with item.
339 free_item(ITEM
*item
)
342 return E_BAD_ARGUMENT
;
344 /* check for connection to menu */
345 if (item
->parent
!= NULL
)
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
);
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
;
365 /* check if we have been called from an init type function */
366 if (menu
->in_init
== 1)
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
;
382 * Return a pointer to the current item for the menu
385 current_item(MENU
*menu
)
390 if (menu
->items
== NULL
)
393 return menu
->items
[menu
->cur_item
];
397 * Return the index into the item array that matches item.
400 item_index(ITEM
*item
)
403 return _menui_default_item
.index
;