*** w32menu.c.ori Mon Jul 15 10:48:32 2002 --- w32menu.c Sun Jul 28 18:35:13 2002 *************** *** 112,120 **** #endif } widget_value; ! /* LocalAlloc/Free is a reasonably good allocator. */ ! #define malloc_widget_value() (void*)LocalAlloc (LMEM_ZEROINIT, sizeof (widget_value)) ! #define free_widget_value(wv) LocalFree (wv) /******************************************************************/ --- 112,124 ---- #endif } widget_value; ! /* Local memory management */ ! #define local_heap (GetProcessHeap ()) ! #define local_alloc(n) (HeapAlloc (local_heap, HEAP_ZERO_MEMORY, (n))) ! #define local_free(p) (HeapFree (local_heap, 0, ((LPVOID) (p)))) ! ! #define malloc_widget_value() ((widget_value *) local_alloc (sizeof (widget_value))) ! #define free_widget_value(wv) (local_free ((wv))) /******************************************************************/ *************** *** 318,324 **** if (menu_items_used + 1 > menu_items_allocated) grow_menu_items (); ! XVECTOR (menu_items)->contents[menu_items_used++] = Qnil; menu_items_submenu_depth++; } --- 322,328 ---- if (menu_items_used + 1 > menu_items_allocated) grow_menu_items (); ! ASET (menu_items, menu_items_used++, Qnil); menu_items_submenu_depth++; } *************** *** 330,336 **** if (menu_items_used + 1 > menu_items_allocated) grow_menu_items (); ! XVECTOR (menu_items)->contents[menu_items_used++] = Qlambda; menu_items_submenu_depth--; } --- 334,340 ---- if (menu_items_used + 1 > menu_items_allocated) grow_menu_items (); ! ASET (menu_items, menu_items_used++, Qlambda); menu_items_submenu_depth--; } *************** *** 342,348 **** if (menu_items_used + 1 > menu_items_allocated) grow_menu_items (); ! XVECTOR (menu_items)->contents[menu_items_used++] = Qquote; } /* Start a new menu pane in menu_items. --- 346,352 ---- if (menu_items_used + 1 > menu_items_allocated) grow_menu_items (); ! ASET (menu_items, menu_items_used++, Qquote); } /* Start a new menu pane in menu_items. *************** *** 357,365 **** if (menu_items_submenu_depth == 0) menu_items_n_panes++; ! XVECTOR (menu_items)->contents[menu_items_used++] = Qt; ! XVECTOR (menu_items)->contents[menu_items_used++] = name; ! XVECTOR (menu_items)->contents[menu_items_used++] = prefix_vec; } /* Push one menu item into the current pane. NAME is the string to --- 361,369 ---- if (menu_items_submenu_depth == 0) menu_items_n_panes++; ! ASET (menu_items, menu_items_used++, Qt); ! ASET (menu_items, menu_items_used++, name); ! ASET (menu_items, menu_items_used++, prefix_vec); } /* Push one menu item into the current pane. NAME is the string to *************** *** 377,390 **** if (menu_items_used + MENU_ITEMS_ITEM_LENGTH > menu_items_allocated) grow_menu_items (); ! XVECTOR (menu_items)->contents[menu_items_used++] = name; ! XVECTOR (menu_items)->contents[menu_items_used++] = enable; ! XVECTOR (menu_items)->contents[menu_items_used++] = key; ! XVECTOR (menu_items)->contents[menu_items_used++] = equiv; ! XVECTOR (menu_items)->contents[menu_items_used++] = def; ! XVECTOR (menu_items)->contents[menu_items_used++] = type; ! XVECTOR (menu_items)->contents[menu_items_used++] = selected; ! XVECTOR (menu_items)->contents[menu_items_used++] = help; } /* Look through KEYMAPS, a vector of keymaps that is NMAPS long, --- 381,394 ---- if (menu_items_used + MENU_ITEMS_ITEM_LENGTH > menu_items_allocated) grow_menu_items (); ! ASET (menu_items, menu_items_used++, name); ! ASET (menu_items, menu_items_used++, enable); ! ASET (menu_items, menu_items_used++, key); ! ASET (menu_items, menu_items_used++, equiv); ! ASET (menu_items, menu_items_used++, def); ! ASET (menu_items, menu_items_used++, type); ! ASET (menu_items, menu_items_used++, selected); ! ASET (menu_items, menu_items_used++, help); } /* Look through KEYMAPS, a vector of keymaps that is NMAPS long, *************** *** 450,462 **** else if (VECTORP (item)) { /* Loop over the char values represented in the vector. */ ! int len = XVECTOR (item)->size; int c; for (c = 0; c < len; c++) { Lisp_Object character; XSETFASTINT (character, c); ! single_menu_item (character, XVECTOR (item)->contents[c], &pending_maps, notreal, maxdepth); } } --- 454,466 ---- else if (VECTORP (item)) { /* Loop over the char values represented in the vector. */ ! int len = ASIZE (item); int c; for (c = 0; c < len; c++) { Lisp_Object character; XSETFASTINT (character, c); ! single_menu_item (character, AREF (item, c), &pending_maps, notreal, maxdepth); } } *************** *** 504,510 **** if (!res) return; /* Not a menu item. */ ! map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP]; if (notreal) { --- 508,514 ---- if (!res) return; /* Not a menu item. */ ! map = AREF (item_properties, ITEM_PROPERTY_MAP); if (notreal) { *************** *** 515,522 **** return; } ! enabled = XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE]; ! item_string = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME]; if (!NILP (map) && SREF (item_string, 0) == '@') { --- 519,526 ---- return; } ! enabled = AREF (item_properties, ITEM_PROPERTY_ENABLE); ! item_string = AREF (item_properties, ITEM_PROPERTY_NAME); if (!NILP (map) && SREF (item_string, 0) == '@') { *************** *** 528,538 **** } push_menu_item (item_string, enabled, key, ! XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF], ! XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ], ! XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE], ! XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED], ! XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]); /* Display a submenu using the toolkit. */ if (! (NILP (map) || NILP (enabled))) --- 532,542 ---- } push_menu_item (item_string, enabled, key, ! AREF (item_properties, ITEM_PROPERTY_DEF), ! AREF (item_properties, ITEM_PROPERTY_KEYEQ), ! AREF (item_properties, ITEM_PROPERTY_TYPE), ! AREF (item_properties, ITEM_PROPERTY_SELECTED), ! AREF (item_properties, ITEM_PROPERTY_HELP)); /* Display a submenu using the toolkit. */ if (! (NILP (map) || NILP (enabled))) *************** *** 745,751 **** /* Make that be the pane title of the first pane. */ if (!NILP (prompt) && menu_items_n_panes >= 0) ! XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME] = prompt; keymaps = 1; } --- 749,755 ---- /* Make that be the pane title of the first pane. */ if (!NILP (prompt) && menu_items_n_panes >= 0) ! ASET (menu_items, MENU_ITEMS_PANE_NAME, prompt); keymaps = 1; } *************** *** 777,783 **** /* Make the title be the pane title of the first pane. */ if (!NILP (title) && menu_items_n_panes >= 0) ! XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME] = title; keymaps = 1; } --- 781,787 ---- /* Make the title be the pane title of the first pane. */ if (!NILP (title) && menu_items_n_panes >= 0) ! ASET (menu_items, MENU_ITEMS_PANE_NAME, title); keymaps = 1; } *************** *** 800,805 **** --- 804,819 ---- } #ifdef HAVE_MENUS + /* If resources from a previous popup menu exist yet, does nothing + until the `menu_free_timer' has freed them (see w32fns.c). + */ + if (current_popup_menu) + { + discard_menu_items (); + UNGCPRO; + return Qnil; + } + /* Display them in a menu. */ BLOCK_INPUT; *************** *** 808,816 **** UNBLOCK_INPUT; discard_menu_items (); UNGCPRO; - #endif /* HAVE_MENUS */ if (error_name) error (error_name); return selection; --- 822,830 ---- UNBLOCK_INPUT; discard_menu_items (); + #endif /* HAVE_MENUS */ UNGCPRO; if (error_name) error (error_name); return selection; *************** *** 981,1005 **** i = 0; while (i < f->menu_bar_items_used) { ! if (EQ (XVECTOR (vector)->contents[i], Qnil)) { subprefix_stack[submenu_depth++] = prefix; prefix = entry; i++; } ! else if (EQ (XVECTOR (vector)->contents[i], Qlambda)) { prefix = subprefix_stack[--submenu_depth]; i++; } ! else if (EQ (XVECTOR (vector)->contents[i], Qt)) { ! prefix = XVECTOR (vector)->contents[i + MENU_ITEMS_PANE_PREFIX]; i += MENU_ITEMS_PANE_LENGTH; } else { ! entry = XVECTOR (vector)->contents[i + MENU_ITEMS_ITEM_VALUE]; /* The EMACS_INT cast avoids a warning. There's no problem as long as pointers have enough bits to hold small integers. */ if ((int) (EMACS_INT) client_data == i) --- 995,1019 ---- i = 0; while (i < f->menu_bar_items_used) { ! if (EQ (AREF (vector, i), Qnil)) { subprefix_stack[submenu_depth++] = prefix; prefix = entry; i++; } ! else if (EQ (AREF (vector, i), Qlambda)) { prefix = subprefix_stack[--submenu_depth]; i++; } ! else if (EQ (AREF (vector, i), Qt)) { ! prefix = AREF (vector, i + MENU_ITEMS_PANE_PREFIX); i += MENU_ITEMS_PANE_LENGTH; } else { ! entry = AREF (vector, i + MENU_ITEMS_ITEM_VALUE); /* The EMACS_INT cast avoids a warning. There's no problem as long as pointers have enough bits to hold small integers. */ if ((int) (EMACS_INT) client_data == i) *************** *** 1051,1056 **** --- 1065,1089 ---- f->output_data.w32->menubar_active = 0; } + /* Return a local copy of the given input string STR. + Does nothing if STR is 0. + + It is necessary to use safe local copy of string data stored in + widget_value because the data part of Lisp strings can be relocated + when the GC compacts string storage. Even when the base string + Lisp_Object is protected! */ + char * + local_string (const char *str) + { + if (str) + { + char *clone = (char *) local_alloc (strlen (str) + 1); + strcpy (clone, str); + return clone; + } + return 0; + } + /* Allocate a widget_value, blocking input. */ widget_value * *************** *** 1075,1081 **** widget_value *wv; { if (! wv) return; ! wv->name = wv->value = wv->key = (char *) 0xDEADBEEF; if (wv->contents && (wv->contents != (widget_value*)1)) --- 1108,1118 ---- widget_value *wv; { if (! wv) return; ! ! local_free (wv->name); ! local_free (wv->value); ! local_free (wv->key); ! wv->name = wv->value = wv->key = (char *) 0xDEADBEEF; if (wv->contents && (wv->contents != (widget_value*)1)) *************** *** 1148,1154 **** submenu_stack = (widget_value **) alloca (menu_items_used * sizeof (widget_value *)); wv = xmalloc_widget_value (); ! wv->name = "menu"; wv->value = 0; wv->enabled = 1; wv->button_type = BUTTON_TYPE_NONE; --- 1185,1191 ---- submenu_stack = (widget_value **) alloca (menu_items_used * sizeof (widget_value *)); wv = xmalloc_widget_value (); ! wv->name = local_string ("menu"); wv->value = 0; wv->enabled = 1; wv->button_type = BUTTON_TYPE_NONE; *************** *** 1164,1203 **** i = previous_items; while (i < menu_items_used) { ! if (EQ (XVECTOR (menu_items)->contents[i], Qnil)) { submenu_stack[submenu_depth++] = save_wv; save_wv = prev_wv; prev_wv = 0; i++; } ! else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda)) { prev_wv = save_wv; save_wv = submenu_stack[--submenu_depth]; i++; } ! else if (EQ (XVECTOR (menu_items)->contents[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 (XVECTOR (menu_items)->contents[i], Qquote)) i += 1; ! else if (EQ (XVECTOR (menu_items)->contents[i], Qt)) { /* Create a new pane. */ Lisp_Object pane_name, prefix; char *pane_string; ! pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME]; ! prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX]; #ifndef HAVE_MULTILINGUAL_MENU if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name)) { pane_name = ENCODE_SYSTEM (pane_name); ! AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name; } #endif pane_string = (NILP (pane_name) --- 1201,1240 ---- i = previous_items; while (i < menu_items_used) { ! 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, prefix; char *pane_string; ! pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME); ! prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX); #ifndef HAVE_MULTILINGUAL_MENU if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name)) { pane_name = ENCODE_SYSTEM (pane_name); ! ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name); } #endif pane_string = (NILP (pane_name) *************** *** 1222,1227 **** --- 1259,1265 ---- This is a kludge, but this isn't worth more time. */ if (!NILP (prefix) && wv->name[0] == '@') wv->name++; + wv->name = local_string (wv->name); wv->value = 0; wv->enabled = 1; wv->button_type = BUTTON_TYPE_NONE; *************** *** 1249,1261 **** if (STRING_MULTIBYTE (item_name)) { item_name = ENCODE_SYSTEM (item_name); ! AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; } if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) { descrip = ENCODE_SYSTEM (descrip); ! AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; } #endif /* not HAVE_MULTILINGUAL_MENU */ --- 1287,1299 ---- 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); } #endif /* not HAVE_MULTILINGUAL_MENU */ *************** *** 1265,1273 **** else save_wv->contents = wv; ! wv->name = (char *) SDATA (item_name); if (!NILP (descrip)) ! wv->key = (char *) SDATA (descrip); wv->value = 0; /* The EMACS_INT cast avoids a warning. There's no problem as long as pointers have enough bits to hold small integers. */ --- 1303,1311 ---- else save_wv->contents = wv; ! wv->name = local_string ((char *) SDATA (item_name)); if (!NILP (descrip)) ! wv->key = local_string ((char *) SDATA (descrip)); wv->value = 0; /* The EMACS_INT cast avoids a warning. There's no problem as long as pointers have enough bits to hold small integers. */ *************** *** 1334,1340 **** deep_p = 1; wv = xmalloc_widget_value (); ! wv->name = "menubar"; wv->value = 0; wv->enabled = 1; wv->button_type = BUTTON_TYPE_NONE; --- 1372,1378 ---- deep_p = 1; wv = xmalloc_widget_value (); ! wv->name = local_string ("menubar"); wv->value = 0; wv->enabled = 1; wv->button_type = BUTTON_TYPE_NONE; *************** *** 1395,1407 **** menu_items = f->menu_bar_vector; menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0; init_menu_items (); ! for (i = 0; i < XVECTOR (items)->size; i += 4) { Lisp_Object key, string, maps; ! key = XVECTOR (items)->contents[i]; ! string = XVECTOR (items)->contents[i + 1]; ! maps = XVECTOR (items)->contents[i + 2]; if (NILP (string)) break; --- 1433,1445 ---- menu_items = f->menu_bar_vector; menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0; init_menu_items (); ! for (i = 0; i < ASIZE (items); i += 4) { Lisp_Object key, string, maps; ! key = AREF (items, i); ! string = AREF (items, i + 1); ! maps = AREF (items, i + 2); if (NILP (string)) break; *************** *** 1426,1432 **** for (i = 0; i < previous_menu_items_used; i++) if (menu_items_used == i ! || (!EQ (previous_items[i], XVECTOR (menu_items)->contents[i]))) break; if (i == menu_items_used && i == previous_menu_items_used && i != 0) { --- 1464,1470 ---- for (i = 0; i < previous_menu_items_used; i++) if (menu_items_used == i ! || (!EQ (previous_items[i], AREF (menu_items, i)))) break; if (i == menu_items_used && i == previous_menu_items_used && i != 0) { *************** *** 1442,1454 **** Windows takes care of this for normal string items, but not for owner-drawn items or additional item-info. */ wv = first_wv->contents; ! for (i = 0; i < XVECTOR (items)->size; i += 4) { Lisp_Object string; ! string = XVECTOR (items)->contents[i + 1]; if (NILP (string)) break; ! wv->name = (char *) SDATA (string); wv = wv->next; } --- 1480,1492 ---- Windows takes care of this for normal string items, but not for owner-drawn items or additional item-info. */ wv = first_wv->contents; ! for (i = 0; i < ASIZE (items); i += 4) { Lisp_Object string; ! string = AREF (items, i + 1); if (NILP (string)) break; ! wv->name = local_string ((char *) SDATA (string)); wv = wv->next; } *************** *** 1462,1477 **** just the top level menu bar strings. */ items = FRAME_MENU_BAR_ITEMS (f); ! for (i = 0; i < XVECTOR (items)->size; i += 4) { Lisp_Object string; ! string = XVECTOR (items)->contents[i + 1]; if (NILP (string)) break; wv = xmalloc_widget_value (); ! wv->name = (char *) SDATA (string); wv->value = 0; wv->enabled = 1; wv->button_type = BUTTON_TYPE_NONE; --- 1500,1515 ---- just the top level menu bar strings. */ items = FRAME_MENU_BAR_ITEMS (f); ! for (i = 0; i < ASIZE (items); i += 4) { Lisp_Object string; ! string = AREF (items, i + 1); if (NILP (string)) break; wv = xmalloc_widget_value (); ! wv->name = local_string ((char *) SDATA (string)); wv->value = 0; wv->enabled = 1; wv->button_type = BUTTON_TYPE_NONE; *************** *** 1613,1619 **** /* Create a tree of widget_value objects representing the panes and their items. */ wv = xmalloc_widget_value (); ! wv->name = "menu"; wv->value = 0; wv->enabled = 1; wv->button_type = BUTTON_TYPE_NONE; --- 1651,1657 ---- /* Create a tree of widget_value objects representing the panes and their items. */ wv = xmalloc_widget_value (); ! wv->name = local_string ("menu"); wv->value = 0; wv->enabled = 1; wv->button_type = BUTTON_TYPE_NONE; *************** *** 1625,1631 **** i = 0; while (i < menu_items_used) { ! if (EQ (XVECTOR (menu_items)->contents[i], Qnil)) { submenu_stack[submenu_depth++] = save_wv; save_wv = prev_wv; --- 1663,1669 ---- i = 0; while (i < menu_items_used) { ! if (EQ (AREF (menu_items, i), Qnil)) { submenu_stack[submenu_depth++] = save_wv; save_wv = prev_wv; *************** *** 1633,1653 **** first_pane = 1; i++; } ! else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda)) { prev_wv = save_wv; save_wv = submenu_stack[--submenu_depth]; first_pane = 0; i++; } ! else if (EQ (XVECTOR (menu_items)->contents[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 (XVECTOR (menu_items)->contents[i], Qquote)) i += 1; ! else if (EQ (XVECTOR (menu_items)->contents[i], Qt)) { /* Create a new pane. */ Lisp_Object pane_name, prefix; --- 1671,1691 ---- first_pane = 1; i++; } ! else if (EQ (AREF (menu_items, i), Qlambda)) { prev_wv = save_wv; save_wv = submenu_stack[--submenu_depth]; first_pane = 0; 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, prefix; *************** *** 1658,1664 **** if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name)) { pane_name = ENCODE_SYSTEM (pane_name); ! AREF (menu_items, i + MENU_ITEMS_PANE_NAME) = pane_name; } #endif pane_string = (NILP (pane_name) --- 1696,1702 ---- if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name)) { pane_name = ENCODE_SYSTEM (pane_name); ! ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name); } #endif pane_string = (NILP (pane_name) *************** *** 1681,1686 **** --- 1719,1725 ---- wv->name = pane_string; if (keymaps && !NILP (prefix)) wv->name++; + wv->name = local_string (wv->name); wv->value = 0; wv->enabled = 1; wv->button_type = BUTTON_TYPE_NONE; *************** *** 1713,1724 **** if (STRINGP (item_name) && STRING_MULTIBYTE (item_name)) { item_name = ENCODE_SYSTEM (item_name); ! AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; } if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) { descrip = ENCODE_SYSTEM (descrip); ! AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; } #endif /* not HAVE_MULTILINGUAL_MENU */ --- 1752,1763 ---- if (STRINGP (item_name) && 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); } #endif /* not HAVE_MULTILINGUAL_MENU */ *************** *** 1727,1735 **** prev_wv->next = wv; else save_wv->contents = wv; ! wv->name = (char *) SDATA (item_name); if (!NILP (descrip)) ! wv->key = (char *) SDATA (descrip); wv->value = 0; /* Use the contents index as call_data, since we are restricted to 16-bits. */ --- 1766,1774 ---- prev_wv->next = wv; else save_wv->contents = wv; ! wv->name = local_string ((char *) SDATA (item_name)); if (!NILP (descrip)) ! wv->key = local_string ((char *) SDATA (descrip)); wv->value = 0; /* Use the contents index as call_data, since we are restricted to 16-bits. */ *************** *** 1765,1771 **** /* Maybe replace this separator with a bitmap or owner-draw item so that it looks better. Having two separators looks odd. */ ! wv_sep->name = "--"; wv_sep->next = first_wv->contents; wv_sep->help = Qnil; --- 1804,1810 ---- /* Maybe replace this separator with a bitmap or owner-draw item so that it looks better. Having two separators looks odd. */ ! wv_sep->name = local_string ("--"); wv_sep->next = first_wv->contents; wv_sep->help = Qnil; *************** *** 1773,1779 **** if (STRING_MULTIBYTE (title)) title = ENCODE_SYSTEM (title); #endif ! wv_title->name = (char *) SDATA (title); wv_title->enabled = TRUE; wv_title->title = TRUE; wv_title->button_type = BUTTON_TYPE_NONE; --- 1812,1818 ---- if (STRING_MULTIBYTE (title)) title = ENCODE_SYSTEM (title); #endif ! wv_title->name = local_string ((char *) SDATA (title)); wv_title->enabled = TRUE; wv_title->title = TRUE; wv_title->button_type = BUTTON_TYPE_NONE; *************** *** 1818,1848 **** i = 0; while (i < menu_items_used) { ! if (EQ (XVECTOR (menu_items)->contents[i], Qnil)) { subprefix_stack[submenu_depth++] = prefix; prefix = entry; i++; } ! else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda)) { prefix = subprefix_stack[--submenu_depth]; i++; } ! else if (EQ (XVECTOR (menu_items)->contents[i], Qt)) { ! prefix ! = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX]; i += MENU_ITEMS_PANE_LENGTH; } /* Ignore a nil in the item list. It's meaningful only for dialog boxes. */ ! else if (EQ (XVECTOR (menu_items)->contents[i], Qquote)) i += 1; else { ! entry ! = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE]; if (menu_item_selection == i) { if (keymaps != 0) --- 1857,1885 ---- i = 0; while (i < menu_items_used) { ! if (EQ (AREF (menu_items, i), Qnil)) { subprefix_stack[submenu_depth++] = prefix; prefix = entry; i++; } ! else if (EQ (AREF (menu_items, i), Qlambda)) { prefix = subprefix_stack[--submenu_depth]; i++; } ! else if (EQ (AREF (menu_items, i), Qt)) { ! prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX); 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 { ! entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE); if (menu_item_selection == i) { if (keymaps != 0) *************** *** 1903,1910 **** { Lisp_Object pane_name, prefix; char *pane_string; ! pane_name = XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME]; ! prefix = XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_PREFIX]; pane_string = (NILP (pane_name) ? "" : (char *) SDATA (pane_name)); prev_wv = xmalloc_widget_value (); --- 1940,1947 ---- { Lisp_Object pane_name, prefix; char *pane_string; ! pane_name = AREF (menu_items, MENU_ITEMS_PANE_NAME); ! prefix = AREF (menu_items, MENU_ITEMS_PANE_PREFIX); pane_string = (NILP (pane_name) ? "" : (char *) SDATA (pane_name)); prev_wv = xmalloc_widget_value (); *************** *** 1924,1934 **** /* Create a new item within current pane. */ Lisp_Object item_name, enable, descrip, help; ! item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME]; ! enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE]; ! descrip ! = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY]; ! help = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_HELP]; if (NILP (item_name)) { --- 1961,1970 ---- /* Create a new item within current pane. */ Lisp_Object item_name, enable, descrip, help; ! 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); ! help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP); if (NILP (item_name)) { *************** *** 1957,1963 **** if (!NILP (descrip)) wv->key = (char *) SDATA (descrip); wv->value = (char *) SDATA (item_name); ! wv->call_data = (void *) &XVECTOR (menu_items)->contents[i]; wv->enabled = !NILP (enable); wv->help = Qnil; prev_wv = wv; --- 1993,1999 ---- if (!NILP (descrip)) wv->key = (char *) SDATA (descrip); wv->value = (char *) SDATA (item_name); ! wv->call_data = (void *) &AREF (menu_items, i); wv->enabled = !NILP (enable); wv->help = Qnil; prev_wv = wv; *************** *** 2027,2042 **** { Lisp_Object entry; ! if (EQ (XVECTOR (menu_items)->contents[i], Qt)) { ! prefix ! = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX]; i += MENU_ITEMS_PANE_LENGTH; } else { ! entry ! = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE]; if (menu_item_selection == i) { if (keymaps != 0) --- 2063,2076 ---- { Lisp_Object entry; ! if (EQ (AREF (menu_items, i), Qt)) { ! prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX); i += MENU_ITEMS_PANE_LENGTH; } else { ! entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE); if (menu_item_selection == i) { if (keymaps != 0) *************** *** 2117,2127 **** we can't deallocate the memory otherwise. */ if (get_menu_item_info) { ! out_string = (char *) LocalAlloc (LPTR, strlen (wv->name) + 1); #ifdef MENU_DEBUG ! DebPrint ("Menu: allocing %ld for owner-draw", info.dwItemData); #endif - strcpy (out_string, wv->name); fuFlags = MF_OWNERDRAW | MF_DISABLED; } else --- 2151,2160 ---- we can't deallocate the memory otherwise. */ if (get_menu_item_info) { ! out_string = local_string (wv->name); #ifdef MENU_DEBUG ! DebPrint ("Menu: allocing %ld for owner-draw", out_string); #endif fuFlags = MF_OWNERDRAW | MF_DISABLED; } else *************** *** 2277,2283 **** #ifdef MENU_DEBUG DebPrint ("Menu: freeing %ld for owner-draw", info.dwItemData); #endif ! LocalFree (info.dwItemData); } /* Recurse down submenus. */ --- 2310,2316 ---- #ifdef MENU_DEBUG DebPrint ("Menu: freeing %ld for owner-draw", info.dwItemData); #endif ! local_free (info.dwItemData); } /* Recurse down submenus. */