diff src/menubar.c @ 251:677f6a0ee643 r20-5b24

Import from CVS: tag r20-5b24
author cvs
date Mon, 13 Aug 2007 10:19:59 +0200
parents 262b8bb4a523
children 11cf20601dec
line wrap: on
line diff
--- a/src/menubar.c	Mon Aug 13 10:19:12 2007 +0200
+++ b/src/menubar.c	Mon Aug 13 10:19:59 2007 +0200
@@ -30,6 +30,7 @@
 #include "buffer.h"
 #include "device.h"
 #include "frame.h"
+#include "gui.h"
 #include "menubar.h"
 #include "redisplay.h"
 #include "window.h"
@@ -93,6 +94,112 @@
   update_frame_menubars (f);
 }
 
+Lisp_Object
+current_frame_menubar (CONST struct frame* f)
+{
+  struct window *w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f));
+  return symbol_value_in_buffer (Qcurrent_menubar, w->buffer);
+}
+
+Lisp_Object
+menu_parse_submenu_keywords (Lisp_Object desc, struct gui_item* pgui_item)
+{
+  /* Menu descriptor should be a list */
+  CHECK_CONS (desc);
+  
+  /* First element may be menu name, although can be omitted.
+     Let's think that if stuff begins with anything than a keyword
+     or a list (submenu), this is a menu name, expected to be a stirng */
+  if (!KEYWORDP (XCAR (desc)) && !CONSP (XCAR (desc)))
+    {
+      CHECK_STRING (XCAR (desc));
+      pgui_item->name = XCAR (desc);
+      desc = XCDR (desc);
+      if (!NILP (desc))
+	CHECK_CONS (desc);
+    }
+
+  /* Walk along all key-value pairs */
+  while (!NILP(desc) && KEYWORDP (XCAR (desc)))
+    {
+      Lisp_Object key, val;
+      key = XCAR (desc);
+      desc = XCDR (desc);
+      CHECK_CONS (desc);
+      val = XCAR (desc);
+      desc = XCDR (desc);
+      if (!NILP (desc))
+	CHECK_CONS (desc);
+      gui_item_add_keyval_pair (pgui_item, key, val);
+    }
+
+  /* Return the rest - supposed to be a list of items */
+  return desc;
+}
+
+DEFUN ("menu-find-real-submenu", Fmenu_find_real_submenu, 2, 2, 0, /*
+Find a submenu descriptor within DESC by following PATH.
+This function finds a submenu descriptor, either from the description
+DESC or generated by a filter within DESC. The function regards :config
+and :included keywords in the DESC, and expands submenus along the
+PATH using :filter functions. Return value is a descriptor for the
+submenu, NOT expanded and NOT checked against :config and :included.
+Also, individual menu items are not looked for, only submenus.
+
+See also 'find-menu-item'
+*/
+       (desc, path))
+{
+  Lisp_Object path_entry, submenu_desc, submenu;
+  struct gcpro gcpro1;
+  struct gui_item gui_item;
+
+  gui_item_init (&gui_item);
+  GCPRO1 (gui_item);
+  gcpro1.nvars = GUI_ITEM_GCPRO_COUNT;
+  
+  EXTERNAL_LIST_LOOP (path_entry, path)
+    {
+      /* Verify that DESC describes a menu, not single item */
+      if (!CONSP (desc))
+	RETURN_UNGCPRO (Qnil);
+
+      /* Parse this menu */
+      desc = menu_parse_submenu_keywords (desc, &gui_item);
+
+      /* Check that this (sub)menu is active */
+      if (!gui_item_active_p (&gui_item))
+	RETURN_UNGCPRO (Qnil);
+
+      /* Apply :filter */
+      if (!NILP (gui_item.filter))
+	desc = call1 (gui_item.filter, desc);
+
+      /* Find the next menu on the path inside this one */
+      EXTERNAL_LIST_LOOP (submenu_desc, desc)
+	{
+	  submenu = XCAR (submenu_desc);
+	  if (CONSP (submenu)
+	      && STRINGP (XCAR (submenu))
+	      && !NILP (Fstring_equal (XCAR (submenu), XCAR (path_entry))))
+	    {
+	      desc = submenu;
+	      goto descend;
+	    }
+	}
+      /* Submenu not found */
+      RETURN_UNGCPRO (Qnil);
+			  
+    descend:
+      /* Prepare for the next iteration */
+      gui_item_init (&gui_item);
+    }
+
+  /* We have successfully descended down the end of the path */
+  UNGCPRO;
+  return desc;
+}
+
 DEFUN ("popup-menu", Fpopup_menu, 1, 2, 0, /*
 Pop up the given menu.
 A menu description is a list of menu items, strings, and submenus.
@@ -239,6 +346,7 @@
   defsymbol (&Qcurrent_menubar, "current-menubar");
   DEFSUBR (Fpopup_menu);
   DEFSUBR (Fnormalize_menu_item_name);
+  DEFSUBR (Fmenu_find_real_submenu);
 }
 
 void