static void free_widget_value_tree (widget_value *wv) { if (!wv) return; free (wv->name); free (wv->value); free (wv->key); wv->name = wv->value = wv->key = (char *) 0xDEADBEEF; if (wv->toolkit_data && wv->free_toolkit_data) { XtFree (wv->toolkit_data); wv->toolkit_data = (void *) 0xDEADBEEF; } if (wv->contents && (wv->contents != (widget_value*)1)) { free_widget_value_tree (wv->contents); wv->contents = (widget_value *) 0xDEADBEEF; } if (wv->next) { free_widget_value_tree (wv->next); wv->next = (widget_value *) 0xDEADBEEF; } free_widget_value (wv); }
void free_widget_value_tree(widget_value * wv) { if (!wv) return; free_widget_value_contents(wv); free_widget_value(wv); }
/* This recursively calls free_widget_value() on the tree of widgets. It must free all data that was malloc'ed for these widget_values. It used to be that emacs only allocated new storage for the `key' slot. All other slots are pointers into the data of Lisp_Strings, and must be left alone. */ void free_popup_widget_value_tree(widget_value * wv) { if (!wv) { return; } if (wv->key) { /* we mustnt free this? */ #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC xfree(wv->key); #endif /* !BDWGC */ } if (wv->value) { /* we mustnt free this? */ #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC xfree(wv->value); #endif /* !BDWGC */ } if (wv->name) { /* we mustnt free this? */ #if !defined HAVE_BDWGC || !defined EF_USE_BDWGC xfree(wv->name); #endif /* !BDWGC */ } #if defined HAVE_BDWGC && defined EF_USE_BDWGC wv->name = wv->value = wv->key = NULL; #else /* !BDWGC */ wv->name = wv->value = wv->key = (char *)0xDEADBEEF; #endif /* BDWGC */ if (wv->contents && (wv->contents != (widget_value *) 1)) { free_popup_widget_value_tree(wv->contents); #if defined HAVE_BDWGC && defined EF_USE_BDWGC wv->contents = NULL; #else /* !BDWGC */ wv->contents = (widget_value *) 0xDEADBEEF; #endif /* BDWGC */ } if (wv->next) { free_popup_widget_value_tree(wv->next); #if defined HAVE_BDWGC && defined EF_USE_BDWGC wv->next = NULL; #else /* !BDWGC */ wv->next = (widget_value *) 0xDEADBEEF; #endif /* BDWGC */ } free_widget_value(wv); return; }
void free_menubar_widget_value_tree (widget_value *wv) { if (! wv) return; wv->name = wv->value = wv->key = (char *) 0xDEADBEEF; if (wv->contents && (wv->contents != (widget_value*)1)) { free_menubar_widget_value_tree (wv->contents); wv->contents = (widget_value *) 0xDEADBEEF; } if (wv->next) { free_menubar_widget_value_tree (wv->next); wv->next = (widget_value *) 0xDEADBEEF; } block_input (); free_widget_value (wv); unblock_input (); }
void free_menubar_widget_value_tree (widget_value *wv) { if (! wv) return; wv->name = wv->value = wv->key = (char *) 0xDEADBEEF; if (wv->contents && (wv->contents != (widget_value*)1)) { free_menubar_widget_value_tree (wv->contents); wv->contents = (widget_value *) 0xDEADBEEF; } if (wv->next) { free_menubar_widget_value_tree (wv->next); wv->next = (widget_value *) 0xDEADBEEF; } BLOCK_INPUT; free_widget_value (wv); UNBLOCK_INPUT; }
/* This recursively calls free_widget_value() on the tree of widgets. It must free all data that was malloc'ed for these widget_values. It used to be that emacs only allocated new storage for the `key' slot. All other slots are pointers into the data of Lisp_Strings, and must be left alone. */ void free_popup_widget_value_tree (widget_value *wv) { if (! wv) return; if (wv->key) xfree (wv->key); if (wv->value) xfree (wv->value); if (wv->name) xfree (wv->name); wv->name = wv->value = wv->key = (char *) 0xDEADBEEF; if (wv->contents && (wv->contents != (widget_value*)1)) { free_popup_widget_value_tree (wv->contents); wv->contents = (widget_value *) 0xDEADBEEF; } if (wv->next) { free_popup_widget_value_tree (wv->next); wv->next = (widget_value *) 0xDEADBEEF; } free_widget_value (wv); }
widget_value * digest_single_submenu (int start, int end, bool top_level_items) { widget_value *wv, *prev_wv, *save_wv, *first_wv; int i; int submenu_depth = 0; widget_value **submenu_stack; bool panes_seen = 0; struct frame *f = XFRAME (Vmenu_updating_frame); submenu_stack = alloca (menu_items_used * sizeof *submenu_stack); wv = xmalloc_widget_value (); wv->name = "menu"; wv->value = 0; wv->enabled = 1; wv->button_type = BUTTON_TYPE_NONE; wv->help = Qnil; first_wv = wv; save_wv = 0; prev_wv = 0; /* Loop over all panes and items made by the preceding call to parse_single_submenu and construct a tree of widget_value objects. Ignore the panes and items used by previous calls to digest_single_submenu, even though those are also in menu_items. */ i = start; while (i < end) { if (EQ (AREF (menu_items, i), Qnil)) { submenu_stack[submenu_depth++] = save_wv; save_wv = prev_wv; prev_wv = 0; i++; } else if (EQ (AREF (menu_items, i), Qlambda)) { prev_wv = save_wv; save_wv = submenu_stack[--submenu_depth]; i++; } else if (EQ (AREF (menu_items, i), Qt) && submenu_depth != 0) i += MENU_ITEMS_PANE_LENGTH; /* Ignore a nil in the item list. It's meaningful only for dialog boxes. */ else if (EQ (AREF (menu_items, i), Qquote)) i += 1; else if (EQ (AREF (menu_items, i), Qt)) { /* Create a new pane. */ Lisp_Object pane_name; const char *pane_string; panes_seen = 1; pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME); /* TTY menus display menu items via tty_write_glyphs, which will encode the strings as appropriate. */ if (!FRAME_TERMCAP_P (f)) { #ifdef HAVE_NTGUI if (STRINGP (pane_name)) { if (unicode_append_menu) /* Encode as UTF-8 for now. */ pane_name = ENCODE_UTF_8 (pane_name); else if (STRING_MULTIBYTE (pane_name)) pane_name = ENCODE_SYSTEM (pane_name); ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name); } #elif defined (USE_LUCID) && defined (HAVE_XFT) if (STRINGP (pane_name)) { pane_name = ENCODE_UTF_8 (pane_name); ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name); } #elif !defined (HAVE_MULTILINGUAL_MENU) if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name)) { pane_name = ENCODE_MENU_STRING (pane_name); ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name); } #endif } pane_string = (NILP (pane_name) ? "" : SSDATA (pane_name)); /* If there is just one top-level pane, put all its items directly under the top-level menu. */ if (menu_items_n_panes == 1) pane_string = ""; /* If the pane has a meaningful name, make the pane a top-level menu item with its items as a submenu beneath it. */ if (strcmp (pane_string, "")) { wv = xmalloc_widget_value (); if (save_wv) save_wv->next = wv; else first_wv->contents = wv; wv->lname = pane_name; /* Set value to 1 so update_submenu_strings can handle '@' */ wv->value = (char *)1; wv->enabled = 1; wv->button_type = BUTTON_TYPE_NONE; wv->help = Qnil; save_wv = wv; } else save_wv = first_wv; prev_wv = 0; i += MENU_ITEMS_PANE_LENGTH; } else { /* Create a new item within current pane. */ Lisp_Object item_name, enable, descrip, def, type, selected; Lisp_Object help; /* All items should be contained in panes. */ if (! panes_seen) emacs_abort (); item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME); enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE); descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY); def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION); type = AREF (menu_items, i + MENU_ITEMS_ITEM_TYPE); selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED); help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP); /* TTY menu items and their descriptions will be encoded by tty_write_glyphs. */ if (!FRAME_TERMCAP_P (f)) { #ifdef HAVE_NTGUI if (STRINGP (item_name)) { if (unicode_append_menu) item_name = ENCODE_UTF_8 (item_name); else if (STRING_MULTIBYTE (item_name)) item_name = ENCODE_SYSTEM (item_name); ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name); } if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) { descrip = ENCODE_SYSTEM (descrip); ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip); } #elif USE_LUCID if (STRINGP (item_name)) { item_name = ENCODE_UTF_8 (item_name); ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name); } if (STRINGP (descrip)) { descrip = ENCODE_UTF_8 (descrip); ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip); } #elif !defined (HAVE_MULTILINGUAL_MENU) if (STRING_MULTIBYTE (item_name)) { item_name = ENCODE_MENU_STRING (item_name); ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name); } if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) { descrip = ENCODE_MENU_STRING (descrip); ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip); } #endif } wv = xmalloc_widget_value (); if (prev_wv) prev_wv->next = wv; else save_wv->contents = wv; wv->lname = item_name; if (!NILP (descrip)) wv->lkey = descrip; wv->value = 0; /* The intptr_t cast avoids a warning. There's no problem as long as pointers have enough bits to hold small integers. */ wv->call_data = (!NILP (def) ? (void *) (intptr_t) i : 0); wv->enabled = !NILP (enable); if (NILP (type)) wv->button_type = BUTTON_TYPE_NONE; else if (EQ (type, QCradio)) wv->button_type = BUTTON_TYPE_RADIO; else if (EQ (type, QCtoggle)) wv->button_type = BUTTON_TYPE_TOGGLE; else emacs_abort (); wv->selected = !NILP (selected); if (! STRINGP (help)) help = Qnil; wv->help = help; prev_wv = wv; i += MENU_ITEMS_ITEM_LENGTH; } } /* If we have just one "menu item" that was originally a button, return it by itself. */ if (top_level_items && first_wv->contents && first_wv->contents->next == 0) { wv = first_wv->contents; free_widget_value (first_wv); return wv; } return first_wv; }