You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

menu.c 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /*
  2. * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. */
  19. FILE_LICENCE ( GPL2_OR_LATER );
  20. /** @file
  21. *
  22. * Menu selection
  23. *
  24. */
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <assert.h>
  28. #include <ipxe/list.h>
  29. #include <ipxe/menu.h>
  30. /** List of all menus */
  31. static LIST_HEAD ( menus );
  32. /**
  33. * Create menu
  34. *
  35. * @v name Menu name, or NULL
  36. * @v title Menu title, or NULL
  37. * @ret menu Menu, or NULL on failure
  38. */
  39. struct menu * create_menu ( const char *name, const char *title ) {
  40. size_t name_len;
  41. size_t title_len;
  42. size_t len;
  43. struct menu *menu;
  44. char *name_copy;
  45. char *title_copy;
  46. /* Destroy any existing menu of this name */
  47. menu = find_menu ( name );
  48. if ( menu )
  49. destroy_menu ( menu );
  50. /* Use empty title if none given */
  51. if ( ! title )
  52. title = "";
  53. /* Allocate menu */
  54. name_len = ( name ? ( strlen ( name ) + 1 /* NUL */ ) : 0 );
  55. title_len = ( strlen ( title ) + 1 /* NUL */ );
  56. len = ( sizeof ( *menu ) + name_len + title_len );
  57. menu = zalloc ( len );
  58. if ( ! menu )
  59. return NULL;
  60. name_copy = ( ( void * ) ( menu + 1 ) );
  61. title_copy = ( name_copy + name_len );
  62. /* Initialise menu */
  63. if ( name ) {
  64. strcpy ( name_copy, name );
  65. menu->name = name_copy;
  66. }
  67. strcpy ( title_copy, title );
  68. menu->title = title_copy;
  69. INIT_LIST_HEAD ( &menu->items );
  70. /* Add to list of menus */
  71. list_add_tail ( &menu->list, &menus );
  72. DBGC ( menu, "MENU %s created with title \"%s\"\n",
  73. menu->name, menu->title );
  74. return menu;
  75. }
  76. /**
  77. * Add menu item
  78. *
  79. * @v menu Menu
  80. * @v label Label, or NULL
  81. * @v text Text, or NULL
  82. * @v shortcut Shortcut key
  83. * @v is_default Item is the default item
  84. * @ret item Menu item, or NULL on failure
  85. */
  86. struct menu_item * add_menu_item ( struct menu *menu, const char *label,
  87. const char *text, int shortcut,
  88. int is_default ) {
  89. size_t label_len;
  90. size_t text_len;
  91. size_t len;
  92. struct menu_item *item;
  93. char *label_copy;
  94. char *text_copy;
  95. /* Use empty text if none given */
  96. if ( ! text )
  97. text = "";
  98. /* Allocate item */
  99. label_len = ( label ? ( strlen ( label ) + 1 /* NUL */ ) : 0 );
  100. text_len = ( strlen ( text ) + 1 /* NUL */ );
  101. len = ( sizeof ( *item ) + label_len + text_len );
  102. item = zalloc ( len );
  103. if ( ! item )
  104. return NULL;
  105. label_copy = ( ( void * ) ( item + 1 ) );
  106. text_copy = ( label_copy + label_len );
  107. /* Initialise item */
  108. if ( label ) {
  109. strcpy ( label_copy, label );
  110. item->label = label_copy;
  111. }
  112. strcpy ( text_copy, text );
  113. item->text = text_copy;
  114. item->shortcut = shortcut;
  115. item->is_default = is_default;
  116. /* Add to list of items */
  117. list_add_tail ( &item->list, &menu->items );
  118. return item;
  119. }
  120. /**
  121. * Destroy menu
  122. *
  123. * @v menu Menu
  124. */
  125. void destroy_menu ( struct menu *menu ) {
  126. struct menu_item *item;
  127. struct menu_item *tmp;
  128. /* Remove from list of menus */
  129. list_del ( &menu->list );
  130. /* Free items */
  131. list_for_each_entry_safe ( item, tmp, &menu->items, list ) {
  132. list_del ( &item->list );
  133. free ( item );
  134. }
  135. /* Free menu */
  136. free ( menu );
  137. }
  138. /**
  139. * Find menu
  140. *
  141. * @v name Menu name, or NULL
  142. * @ret menu Menu, or NULL if not found
  143. */
  144. struct menu * find_menu ( const char *name ) {
  145. struct menu *menu;
  146. list_for_each_entry ( menu, &menus, list ) {
  147. if ( ( menu->name == name ) ||
  148. ( strcmp ( menu->name, name ) == 0 ) ) {
  149. return menu;
  150. }
  151. }
  152. return NULL;
  153. }