Mercurial > emacs
comparison src/macmenu.c @ 70148:a2348b30cc21
(restore_menu_items, save_menu_items): New functions from xmenu.c.
(set_frame_menubar, digest_single_submenu): Apply 2006-04-18
changes for xmenu.c.
| author | YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> |
|---|---|
| date | Fri, 21 Apr 2006 07:56:47 +0000 |
| parents | adc2f96580af |
| children | eb5777232ca5 2ecafc6d5db7 |
comparison
equal
deleted
inserted
replaced
| 70147:37f988f09f67 | 70148:a2348b30cc21 |
|---|---|
| 301 menu_items = Qnil; | 301 menu_items = Qnil; |
| 302 menu_items_allocated = 0; | 302 menu_items_allocated = 0; |
| 303 } | 303 } |
| 304 } | 304 } |
| 305 | 305 |
| 306 /* This undoes save_menu_items, and it is called by the specpdl unwind | |
| 307 mechanism. */ | |
| 308 | |
| 309 static Lisp_Object | |
| 310 restore_menu_items (saved) | |
| 311 Lisp_Object saved; | |
| 312 { | |
| 313 menu_items = XCAR (saved); | |
| 314 menu_items_allocated = (VECTORP (menu_items) ? ASIZE (menu_items) : 0); | |
| 315 saved = XCDR (saved); | |
| 316 menu_items_used = XINT (XCAR (saved)); | |
| 317 saved = XCDR (saved); | |
| 318 menu_items_n_panes = XINT (XCAR (saved)); | |
| 319 saved = XCDR (saved); | |
| 320 menu_items_submenu_depth = XINT (XCAR (saved)); | |
| 321 } | |
| 322 | |
| 323 /* Push the whole state of menu_items processing onto the specpdl. | |
| 324 It will be restored when the specpdl is unwound. */ | |
| 325 | |
| 326 static void | |
| 327 save_menu_items () | |
| 328 { | |
| 329 Lisp_Object saved = list4 (menu_items, | |
| 330 make_number (menu_items_used), | |
| 331 make_number (menu_items_n_panes), | |
| 332 make_number (menu_items_submenu_depth)); | |
| 333 record_unwind_protect (restore_menu_items, saved); | |
| 334 menu_items = Qnil; | |
| 335 } | |
| 336 | |
| 306 /* Make the menu_items vector twice as large. */ | 337 /* Make the menu_items vector twice as large. */ |
| 307 | 338 |
| 308 static void | 339 static void |
| 309 grow_menu_items () | 340 grow_menu_items () |
| 310 { | 341 { |
| 311 Lisp_Object old; | 342 Lisp_Object old; |
| 312 int old_size = menu_items_allocated; | 343 int old_size = menu_items_allocated; |
| 313 old = menu_items; | 344 old = menu_items; |
| 314 | 345 |
| 315 menu_items_allocated *= 2; | 346 menu_items_allocated *= 2; |
| 347 | |
| 316 menu_items = Fmake_vector (make_number (menu_items_allocated), Qnil); | 348 menu_items = Fmake_vector (make_number (menu_items_allocated), Qnil); |
| 317 bcopy (XVECTOR (old)->contents, XVECTOR (menu_items)->contents, | 349 bcopy (XVECTOR (old)->contents, XVECTOR (menu_items)->contents, |
| 318 old_size * sizeof (Lisp_Object)); | 350 old_size * sizeof (Lisp_Object)); |
| 319 } | 351 } |
| 320 | 352 |
| 1183 { | 1215 { |
| 1184 widget_value *wv, *prev_wv, *save_wv, *first_wv; | 1216 widget_value *wv, *prev_wv, *save_wv, *first_wv; |
| 1185 int i; | 1217 int i; |
| 1186 int submenu_depth = 0; | 1218 int submenu_depth = 0; |
| 1187 widget_value **submenu_stack; | 1219 widget_value **submenu_stack; |
| 1220 int panes_seen = 0; | |
| 1188 | 1221 |
| 1189 submenu_stack | 1222 submenu_stack |
| 1190 = (widget_value **) alloca (menu_items_used * sizeof (widget_value *)); | 1223 = (widget_value **) alloca (menu_items_used * sizeof (widget_value *)); |
| 1191 wv = xmalloc_widget_value (); | 1224 wv = xmalloc_widget_value (); |
| 1192 wv->name = "menu"; | 1225 wv->name = "menu"; |
| 1228 else if (EQ (XVECTOR (menu_items)->contents[i], Qt)) | 1261 else if (EQ (XVECTOR (menu_items)->contents[i], Qt)) |
| 1229 { | 1262 { |
| 1230 /* Create a new pane. */ | 1263 /* Create a new pane. */ |
| 1231 Lisp_Object pane_name, prefix; | 1264 Lisp_Object pane_name, prefix; |
| 1232 char *pane_string; | 1265 char *pane_string; |
| 1266 | |
| 1267 panes_seen++; | |
| 1233 | 1268 |
| 1234 pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME]; | 1269 pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME]; |
| 1235 prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX]; | 1270 prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX]; |
| 1236 | 1271 |
| 1237 #ifndef HAVE_MULTILINGUAL_MENU | 1272 #ifndef HAVE_MULTILINGUAL_MENU |
| 1276 { | 1311 { |
| 1277 /* Create a new item within current pane. */ | 1312 /* Create a new item within current pane. */ |
| 1278 Lisp_Object item_name, enable, descrip, def, type, selected; | 1313 Lisp_Object item_name, enable, descrip, def, type, selected; |
| 1279 Lisp_Object help; | 1314 Lisp_Object help; |
| 1280 | 1315 |
| 1316 /* All items should be contained in panes. */ | |
| 1317 if (panes_seen == 0) | |
| 1318 abort (); | |
| 1319 | |
| 1281 item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME); | 1320 item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME); |
| 1282 enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE); | 1321 enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE); |
| 1283 descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY); | 1322 descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY); |
| 1284 def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION); | 1323 def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION); |
| 1285 type = AREF (menu_items, i + MENU_ITEMS_ITEM_TYPE); | 1324 type = AREF (menu_items, i + MENU_ITEMS_ITEM_TYPE); |
| 1527 bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items, | 1566 bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items, |
| 1528 previous_menu_items_used * sizeof (Lisp_Object)); | 1567 previous_menu_items_used * sizeof (Lisp_Object)); |
| 1529 | 1568 |
| 1530 /* Fill in menu_items with the current menu bar contents. | 1569 /* Fill in menu_items with the current menu bar contents. |
| 1531 This can evaluate Lisp code. */ | 1570 This can evaluate Lisp code. */ |
| 1571 save_menu_items (); | |
| 1572 | |
| 1532 menu_items = f->menu_bar_vector; | 1573 menu_items = f->menu_bar_vector; |
| 1533 menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0; | 1574 menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0; |
| 1534 submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *)); | 1575 submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *)); |
| 1535 submenu_end = (int *) alloca (XVECTOR (items)->size * sizeof (int *)); | 1576 submenu_end = (int *) alloca (XVECTOR (items)->size * sizeof (int *)); |
| 1536 submenu_n_panes = (int *) alloca (XVECTOR (items)->size * sizeof (int)); | 1577 submenu_n_panes = (int *) alloca (XVECTOR (items)->size * sizeof (int)); |
| 1586 wv->button_type = BUTTON_TYPE_NONE; | 1627 wv->button_type = BUTTON_TYPE_NONE; |
| 1587 prev_wv = wv; | 1628 prev_wv = wv; |
| 1588 } | 1629 } |
| 1589 | 1630 |
| 1590 set_buffer_internal_1 (prev); | 1631 set_buffer_internal_1 (prev); |
| 1591 unbind_to (specpdl_count, Qnil); | |
| 1592 | 1632 |
| 1593 /* If there has been no change in the Lisp-level contents | 1633 /* If there has been no change in the Lisp-level contents |
| 1594 of the menu bar, skip redisplaying it. Just exit. */ | 1634 of the menu bar, skip redisplaying it. Just exit. */ |
| 1595 | 1635 |
| 1636 /* Compare the new menu items with the ones computed last time. */ | |
| 1596 for (i = 0; i < previous_menu_items_used; i++) | 1637 for (i = 0; i < previous_menu_items_used; i++) |
| 1597 if (menu_items_used == i | 1638 if (menu_items_used == i |
| 1598 || (!EQ (previous_items[i], XVECTOR (menu_items)->contents[i]))) | 1639 || (!EQ (previous_items[i], XVECTOR (menu_items)->contents[i]))) |
| 1599 break; | 1640 break; |
| 1600 if (i == menu_items_used && i == previous_menu_items_used && i != 0) | 1641 if (i == menu_items_used && i == previous_menu_items_used && i != 0) |
| 1601 { | 1642 { |
| 1643 /* The menu items have not changed. Don't bother updating | |
| 1644 the menus in any form, since it would be a no-op. */ | |
| 1602 free_menubar_widget_value_tree (first_wv); | 1645 free_menubar_widget_value_tree (first_wv); |
| 1603 discard_menu_items (); | 1646 discard_menu_items (); |
| 1604 | 1647 unbind_to (specpdl_count, Qnil); |
| 1605 return; | 1648 return; |
| 1606 } | 1649 } |
| 1650 | |
| 1651 /* The menu items are different, so store them in the frame. */ | |
| 1652 f->menu_bar_vector = menu_items; | |
| 1653 f->menu_bar_items_used = menu_items_used; | |
| 1654 | |
| 1655 /* This calls restore_menu_items to restore menu_items, etc., | |
| 1656 as they were outside. */ | |
| 1657 unbind_to (specpdl_count, Qnil); | |
| 1607 | 1658 |
| 1608 /* Now GC cannot happen during the lifetime of the widget_value, | 1659 /* Now GC cannot happen during the lifetime of the widget_value, |
| 1609 so it's safe to store data from a Lisp_String. */ | 1660 so it's safe to store data from a Lisp_String. */ |
| 1610 wv = first_wv->contents; | 1661 wv = first_wv->contents; |
| 1611 for (i = 0; i < XVECTOR (items)->size; i += 4) | 1662 for (i = 0; i < XVECTOR (items)->size; i += 4) |
| 1617 wv->name = (char *) SDATA (string); | 1668 wv->name = (char *) SDATA (string); |
| 1618 update_submenu_strings (wv->contents); | 1669 update_submenu_strings (wv->contents); |
| 1619 wv = wv->next; | 1670 wv = wv->next; |
| 1620 } | 1671 } |
| 1621 | 1672 |
| 1622 f->menu_bar_vector = menu_items; | |
| 1623 f->menu_bar_items_used = menu_items_used; | |
| 1624 discard_menu_items (); | |
| 1625 } | 1673 } |
| 1626 else | 1674 else |
| 1627 { | 1675 { |
| 1628 /* Make a widget-value tree containing | 1676 /* Make a widget-value tree containing |
| 1629 just the top level menu bar strings. */ | 1677 just the top level menu bar strings. */ |
