X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/041fa0d4e3df71f79e0c8b35b7ee4ec34578580c..659f64e909614e62b939087c625fd9abfbcf7073:/src/menu.c diff --git a/src/menu.c b/src/menu.c index 2cf94924ff..74d455a8c0 100644 --- a/src/menu.c +++ b/src/menu.c @@ -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 . */ #include #include +#include #include "lisp.h" #include "keyboard.h" @@ -36,51 +37,22 @@ along with GNU Emacs. If not, see . */ #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) } -#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 ()