]> code.delx.au - gnu-emacs/blobdiff - src/menu.c
Reword header comment to prevent copyright.el wanting to update years.
[gnu-emacs] / src / menu.c
index 2cf94924ffdbf5ab1129d2c9045563babf303c31..74d455a8c0ab5c0ceff507638be96e2bce1f2b99 100644 (file)
@@ -1,6 +1,6 @@
 /* Platform-independent code for terminal communications.
    Copyright (C) 1986, 1988, 1993, 1994, 1996, 1999, 2000, 2001, 2002, 2003,
-                 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+                 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -19,6 +19,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include <stdio.h>
+#include <setjmp.h>
 
 #include "lisp.h"
 #include "keyboard.h"
@@ -36,51 +37,22 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "xterm.h"
 #endif
 
+#ifdef HAVE_NS
+#include "nsterm.h"
+#endif
+
 #ifdef USE_GTK
 #include "gtkutil.h"
 #endif
 
 #ifdef HAVE_NTGUI
-/* Definitions copied from lwlib.h */
-typedef void * XtPointer;
-typedef char Boolean;
-enum button_type
-{
-  BUTTON_TYPE_NONE,
-  BUTTON_TYPE_TOGGLE,
-  BUTTON_TYPE_RADIO
-};
-
-/* This structure is based on the one in ../lwlib/lwlib.h  */
-typedef struct _widget_value
-{
-  Lisp_Object   lname;
-  char*                name;
-  char*                value;
-  Lisp_Object   lkey;
-  char*                key;
-  Lisp_Object  help;
-  Boolean      enabled;
-  Boolean      selected;
-  enum button_type button_type;
-  Boolean       title;
-  struct _widget_value*        contents;
-  XtPointer    call_data;
-  struct _widget_value*        next;
-} 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)))
+#include "w32term.h"
 
 extern AppendMenuW_Proc unicode_append_menu;
 
 #endif /* HAVE_NTGUI  */
 
+#include "menu.h"
 
 /* Define HAVE_BOXES if menus can handle radio and toggle buttons.  */
 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
@@ -394,7 +366,7 @@ single_menu_item (key, item, dummy, skp_v)
       return;
     }
 
-#ifdef HAVE_X_WINDOWS
+#if defined(HAVE_X_WINDOWS) || defined(MSDOS)
 #ifndef HAVE_BOXES
   /* Simulate radio buttons and toggle boxes by putting a prefix in
      front of them.  */
@@ -464,7 +436,7 @@ single_menu_item (key, item, dummy, skp_v)
     item_string = concat2 (item_string, build_string (" >"));
 #endif
 
-#endif /* HAVE_X_WINDOWS */
+#endif /* HAVE_X_WINDOWS || MSDOS */
 
   push_menu_item (item_string, enabled, key,
                  XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF],
@@ -473,7 +445,7 @@ single_menu_item (key, item, dummy, skp_v)
                  XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED],
                  XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]);
 
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (HAVE_NTGUI)
   /* Display a submenu using the toolkit.  */
   if (! (NILP (map) || NILP (enabled)))
     {
@@ -613,7 +585,7 @@ parse_single_submenu (item_key, item_name, maps)
 }
 
 \f
-#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (HAVE_NTGUI)
 
 /* Allocate a widget_value, blocking input.  */
 
@@ -910,7 +882,7 @@ update_submenu_strings (first_wv)
 void
 find_and_call_menu_selection (f, menu_bar_items_used, vector, client_data)
      FRAME_PTR f;
-     EMACS_INT menu_bar_items_used;
+     int menu_bar_items_used;
      Lisp_Object vector;
      void *client_data;
 {
@@ -989,7 +961,72 @@ find_and_call_menu_selection (f, menu_bar_items_used, vector, client_data)
     }
 }
 
-#endif /* USE_X_TOOLKIT || USE_GTK || HAVE_NTGUI */
+#endif /* USE_X_TOOLKIT || USE_GTK || HAVE_NS || HAVE_NTGUI */
+
+#ifdef HAVE_NS
+/* As above, but return the menu selection instead of storing in kb buffer.
+   If keymaps==1, return full prefixes to selection. */
+Lisp_Object
+find_and_return_menu_selection (FRAME_PTR f, int keymaps, void *client_data)
+{
+  Lisp_Object prefix, entry;
+  int i;
+  Lisp_Object *subprefix_stack;
+  int submenu_depth = 0;
+
+  prefix = entry = Qnil;
+  i = 0;
+  subprefix_stack =
+    (Lisp_Object *)alloca(menu_items_used * sizeof (Lisp_Object));
+
+  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 ((EMACS_INT)client_data ==  (EMACS_INT)(&XVECTOR (menu_items)->contents[i]))
+            {
+              if (keymaps != 0)
+                {
+                  int j;
+
+                  entry = Fcons (entry, Qnil);
+                  if (!NILP (prefix))
+                    entry = Fcons (prefix, entry);
+                  for (j = submenu_depth - 1; j >= 0; j--)
+                    if (!NILP (subprefix_stack[j]))
+                      entry = Fcons (subprefix_stack[j], entry);
+                }
+              return entry;
+            }
+          i += MENU_ITEMS_ITEM_LENGTH;
+        }
+    }
+  return Qnil;
+}
+#endif  /* HAVE_NS */
 
 void
 syms_of_menu ()