Home | History | Annotate | Line # | Download | only in libmenu
item.c revision 1.1.1.1
      1 /*      $Id: item.c,v 1.1.1.1 1999/11/23 11:12:34 blymn Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 1998-1999 Brett Lymn (blymn (at) baea.com.au, brett_lymn (at) yahoo.com)
      5  * All rights reserved.
      6  *
      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 withough specific prior written permission
     14  *
     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.
     25  *
     26  *
     27  */
     28 
     29 #include <menu.h>
     30 #include <strings.h>
     31 #include <malloc.h>
     32 
     33 /* the following is defined in menu.c - it is the default menu struct */
     34 extern MENU _menui_default_menu;
     35 
     36 /* keep default item options for setting in new_item */
     37 ITEM _menui_default_item = {
     38 	{NULL, 0}, /* item name struct */
     39 	{NULL, 0}, /* item description struct */
     40 	NULL, /* user pointer */
     41 	0, /* is item visible? */
     42 	0, /* is item selected? */
     43 	0, /* row item is on */
     44 	0, /* column item is on */
     45 	O_SELECTABLE, /* item options */
     46 	NULL, /* parent menu item is bound to */
     47 	-1, /* index number if item attached to a menu */
     48 	NULL, /* left neighbour */
     49 	NULL, /* right neighbour */
     50 	NULL, /* up neighbour */
     51 	NULL /* down neighbour */
     52 };
     53 
     54 /*
     55  * Return the item visibility flag
     56  */
     57 int
     58 item_visible(item)
     59         ITEM *item;
     60 {
     61 	if (item == NULL)
     62 		return E_BAD_ARGUMENT;
     63 	if (item->parent == NULL)
     64 		return E_NOT_CONNECTED;
     65 
     66         return item->visible;
     67 }
     68 
     69 /*
     70  * Return the pointer to the item name
     71  */
     72 char *
     73 item_name(item)
     74         ITEM *item;
     75 {
     76 	if (item == NULL)
     77 		return NULL;
     78 
     79         return item->name.string;
     80 }
     81 
     82 /*
     83  * Return the pointer to the item description
     84  */
     85 char *
     86 item_description(item)
     87         ITEM *item;
     88 {
     89 	if (item == NULL)
     90 		return NULL;
     91 
     92         return item->description.string;
     93 }
     94 
     95 /*
     96  * Set the application defined function called when the menu is posted or
     97  * just after the current item changes.
     98  */
     99 int
    100 set_item_init(menu, func)
    101         MENU *menu;
    102 	_menui_menu_hook func;
    103 {
    104 	if (menu == NULL)
    105 		_menui_default_menu.item_init = func;
    106 	else
    107 		menu->item_init = func;
    108         return E_OK;
    109 }
    110 
    111 
    112 /*
    113  * Return a pointer to the item initialisation routine.
    114  */
    115 _menui_menu_hook
    116 item_init(menu)
    117         MENU *menu;
    118 {
    119 	if (menu == NULL)
    120 		return _menui_default_menu.item_init;
    121 	else
    122 		return menu->item_init;
    123 }
    124 
    125 /*
    126  * Set the user defined function to be called when menu is unposted or just
    127  * before the current item changes.
    128  */
    129 int
    130 set_item_term(menu, func)
    131         MENU *menu;
    132         _menui_menu_hook func;
    133 {
    134 	if (menu == NULL)
    135 		_menui_default_menu.item_term = func;
    136 	else
    137 		menu->item_term = func;
    138         return E_OK;
    139 }
    140 
    141 /*
    142  * Return a pointer to the termination function
    143  */
    144 _menui_menu_hook
    145 item_term(menu)
    146         MENU *menu;
    147 {
    148 	if (menu == NULL)
    149 		return _menui_default_menu.item_term;
    150 	else
    151 		return menu->item_term;
    152 }
    153 
    154 /*
    155  * Set the item options.  We keep a global copy of the current item options
    156  * as subsequent new_item calls will use the updated options as their
    157  * defaults.
    158  */
    159 int
    160 set_item_opts(item, opts)
    161         ITEM *item;
    162         OPTIONS opts;
    163 {
    164           /* selectable seems to be the only allowable item opt! */
    165         if (opts != O_SELECTABLE)
    166                 return E_SYSTEM_ERROR;
    167 
    168 	if (item == NULL)
    169 		_menui_default_item.opts = opts;
    170 	else
    171 		item->opts = opts;
    172         return E_OK;
    173 }
    174 
    175 /*
    176  * Set item options on.
    177  */
    178 int
    179 item_opts_on(item, opts)
    180         ITEM *item;
    181         OPTIONS opts;
    182 {
    183         if (opts != O_SELECTABLE)
    184                 return E_SYSTEM_ERROR;
    185 
    186         if (item == NULL)
    187 		_menui_default_item.opts |= opts;
    188 	else
    189 		item->opts |= opts;
    190         return E_OK;
    191 }
    192 
    193 /*
    194  * Turn off the named options.
    195  */
    196 int
    197 item_opts_off(item, opts)
    198         ITEM *item;
    199         OPTIONS opts;
    200 {
    201         if (opts != O_SELECTABLE)
    202                 return E_SYSTEM_ERROR;
    203 
    204 	if (item == NULL)
    205 		_menui_default_item.opts &= ~(opts);
    206 	else
    207 		item->opts &= ~(opts);
    208         return E_OK;
    209 }
    210 
    211 /*
    212  * Return the current options set in item.
    213  */
    214 OPTIONS
    215 item_opts(item)
    216         ITEM *item;
    217 {
    218 	if (item == NULL)
    219 		return _menui_default_item.opts;
    220 	else
    221 		return item->opts;
    222 }
    223 
    224 /*
    225  * Set the selected flag of the item iff the menu options allow it.
    226  */
    227 int
    228 set_item_value(param_item, flag)
    229         ITEM *param_item;
    230         int flag;
    231 {
    232 	ITEM *item = (param_item != NULL) ? param_item : &_menui_default_item;
    233 
    234           /* not bound to a menu */
    235         if (item->parent == NULL)
    236                 return E_NOT_CONNECTED;
    237 
    238           /* menu options do not allow multi-selection */
    239         if ((item->parent->opts & O_ONEVALUE) == O_ONEVALUE)
    240                 return E_REQUEST_DENIED;
    241 
    242         item->selected = flag;
    243         return E_OK;
    244 }
    245 
    246 /*
    247  * Return the item value of the item.
    248  */
    249 int
    250 item_value(item)
    251         ITEM *item;
    252 {
    253 	if (item == NULL)
    254 		return _menui_default_item.selected;
    255 	else
    256 		return item->selected;
    257 }
    258 
    259 /*
    260  * Allocate a new item and return the pointer to the newly allocated
    261  * structure.
    262  */
    263 ITEM *
    264 new_item(name, description)
    265         char *name;
    266         char *description;
    267 {
    268         ITEM *new_one;
    269 
    270 	  /* allocate a new item structure for ourselves */
    271         if ((new_one = (ITEM *)malloc(sizeof(ITEM))) == NULL)
    272                 return NULL;
    273 
    274 	  /* copy in the defaults for the item */
    275 	bcopy(&_menui_default_item, new_one, sizeof(ITEM));
    276 
    277 	  /* fill in the name structure - first the length and then
    278 	     allocate room for the string & copy that. */
    279 	new_one->name.length = strlen(name);
    280         if ((new_one->name.string = (char *)
    281              malloc(sizeof(char) * new_one->name.length + 1)) == NULL) {
    282 		  /* uh oh malloc failed - clean up & exit */
    283 		free(new_one);
    284                 return NULL;
    285         }
    286 
    287         strcpy(new_one->name.string, name);
    288 
    289 	  /* fill in the description structure, stash the length then
    290 	     allocate room for description string and copy it in */
    291         new_one->description.length = strlen(description);
    292         if ((new_one->description.string = (char *)
    293              malloc(sizeof(char) * new_one->description.length + 1)) == NULL) {
    294 		  /* malloc has failed - free up allocated memory and return */
    295 		free(new_one->name.string);
    296 		free(new_one);
    297 		return NULL;
    298 	}
    299 
    300 	strcpy(new_one->description.string, description);
    301 
    302 	return new_one;
    303 }
    304 
    305 /*
    306  * Free the allocated storage associated with item.
    307  */
    308 int
    309 free_item(item)
    310 	ITEM *item;
    311 {
    312 	if (item == NULL)
    313 		return E_BAD_ARGUMENT;
    314 
    315 	  /* check for connection to menu */
    316 	if (item->parent != NULL)
    317 		return E_CONNECTED;
    318 
    319 	  /* no connections, so free storage starting with the strings */
    320 	free(item->name.string);
    321 	free(item->description.string);
    322 	free(item);
    323 	return E_OK;
    324 }
    325 
    326 /*
    327  * Set the menu's current item to the one given.
    328  */
    329 int
    330 set_current_item(param_menu, item)
    331 	MENU *param_menu;
    332 	ITEM *item;
    333 {
    334 	MENU *menu = (param_menu != NULL) ? param_menu : &_menui_default_menu;
    335 	int i = 0;
    336 
    337 	  /* check if we have been called from an init type function */
    338 	if (menu->in_init == 1)
    339 		return E_BAD_STATE;
    340 
    341 	  /* check we have items in the menu */
    342 	if (menu->items == NULL)
    343 		return E_NOT_CONNECTED;
    344 
    345 	if ((i = item_index(item)) < 0)
    346 		  /* item must not be a part of this menu */
    347 		return E_BAD_ARGUMENT;
    348 
    349 	menu->cur_item = i;
    350 	return E_OK;
    351 }
    352 
    353 /*
    354  * Return a pointer to the current item for the menu
    355  */
    356 ITEM *
    357 current_item(menu)
    358 	MENU *menu;
    359 {
    360 	if (menu == NULL)
    361 		return NULL;
    362 
    363 	if (menu->items == NULL)
    364 		return NULL;
    365 
    366 	return menu->items[menu->cur_item];
    367 }
    368 
    369 /*
    370  * Return the index into the item array that matches item.
    371  */
    372 int
    373 item_index(item)
    374 	ITEM *item;
    375 {
    376 	if (item == NULL)
    377 		return _menui_default_item.index;
    378 	else
    379 		return item->index;
    380 }
    381