/* Menu support for GNU Emacs on the Microsoft Windows API.
- Copyright (C) 1986, 1988, 1993-1994, 1996, 1998-1999, 2001-2013 Free
+ Copyright (C) 1986, 1988, 1993-1994, 1996, 1998-1999, 2001-2014 Free
Software Foundation, Inc.
This file is part of GNU Emacs.
MessageBoxW_Proc unicode_message_box = NULL;
#endif /* NTGUI_UNICODE */
-Lisp_Object Qdebug_on_next_call;
+Lisp_Object Qdebug_on_next_call, Qunsupported__w32_dialog;
void set_frame_menubar (struct frame *, bool, bool);
#ifdef HAVE_DIALOGS
-static Lisp_Object w32_dialog_show (struct frame *, int, Lisp_Object, char**);
+static Lisp_Object w32_dialog_show (struct frame *, Lisp_Object, Lisp_Object, char **);
#else
static int is_simple_dialog (Lisp_Object);
static Lisp_Object simple_dialog_show (struct frame *, Lisp_Object, Lisp_Object);
void w32_free_menu_strings (HWND);
-#ifdef HAVE_DIALOGS
Lisp_Object
w32_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents)
{
- Lisp_Object title;
- char *error_name;
- Lisp_Object selection;
check_window_system (f);
- /* Decode the dialog items from what was specified. */
- title = Fcar (contents);
- CHECK_STRING (title);
+#ifndef HAVE_DIALOGS
- list_of_panes (Fcons (contents, Qnil));
+ /* Handle simple Yes/No choices as MessageBox popups. */
+ if (is_simple_dialog (contents))
+ return simple_dialog_show (f, contents, header);
+ else
+ return Qunsupported__w32_dialog;
+#else /* HAVE_DIALOGS */
+ {
+ Lisp_Object title;
+ char *error_name;
+ Lisp_Object selection;
- /* Display them in a dialog box. */
- block_input ();
- selection = w32_dialog_show (f, 0, title, header, &error_name);
- unblock_input ();
+ /* Decode the dialog items from what was specified. */
+ title = Fcar (contents);
+ CHECK_STRING (title);
- discard_menu_items ();
- FRAME_DISPLAY_INFO (f)->grabbed = 0;
+ list_of_panes (Fcons (contents, Qnil));
- if (error_name) error (error_name);
- return selection;
-}
+ /* Display them in a dialog box. */
+ block_input ();
+ selection = w32_dialog_show (f, title, header, &error_name);
+ unblock_input ();
+
+ discard_menu_items ();
+ FRAME_DISPLAY_INFO (f)->grabbed = 0;
+
+ if (error_name) error (error_name);
+ return selection;
+ }
#endif /* HAVE_DIALOGS */
+}
/* Activate the menu bar of frame F.
This is called from keyboard.c when it gets the
struct buffer *prev = current_buffer;
Lisp_Object buffer;
- ptrdiff_t specpdl_count = SPECPDL_INDEX ();
+ dynwind_begin ();
int previous_menu_items_used = f->menu_bar_items_used;
Lisp_Object *previous_items
= (Lisp_Object *) alloca (previous_menu_items_used
/* Convert menu_items into widget_value trees
to display the menu. This cannot evaluate Lisp code. */
- wv = xmalloc_widget_value ();
- wv->name = "menubar";
- wv->value = 0;
- wv->enabled = 1;
+ wv = make_widget_value ("menubar", NULL, true, Qnil);
wv->button_type = BUTTON_TYPE_NONE;
- wv->help = Qnil;
first_wv = wv;
for (i = 0; i < last_i; i += 4)
{
free_menubar_widget_value_tree (first_wv);
discard_menu_items ();
- unbind_to (specpdl_count, Qnil);
+ dynwind_end ();
return;
}
f->menu_bar_items_used = menu_items_used;
/* This undoes save_menu_items. */
- unbind_to (specpdl_count, Qnil);
+ dynwind_end ();
/* Now GC cannot happen during the lifetime of the widget_value,
so it's safe to store data from a Lisp_String, as long as
/* Make a widget-value tree containing
just the top level menu bar strings. */
- wv = xmalloc_widget_value ();
- wv->name = "menubar";
- wv->value = 0;
- wv->enabled = 1;
+ wv = make_widget_value ("menubar", NULL, true, Qnil);
wv->button_type = BUTTON_TYPE_NONE;
- wv->help = Qnil;
first_wv = wv;
items = FRAME_MENU_BAR_ITEMS (f);
if (NILP (string))
break;
- wv = xmalloc_widget_value ();
- wv->name = SSDATA (string);
- wv->value = 0;
- wv->enabled = 1;
+ wv = make_widget_value (SSDATA (string), NULL, true, Qnil);
wv->button_type = BUTTON_TYPE_NONE;
- wv->help = Qnil;
/* This prevents lwlib from assuming this
menu item is really supposed to be empty. */
/* The EMACS_INT cast avoids a warning.
/* F is the frame the menu is for.
X and Y are the frame-relative specified position,
relative to the inside upper left corner of the frame F.
- FOR_CLICK is nonzero if this menu was invoked for a mouse click.
- KEYMAPS is 1 if this menu was specified with keymaps;
+ Bitfield MENUFLAGS bits are:
+ MENU_FOR_CLICK is set if this menu was invoked for a mouse click.
+ MENU_KEYMAPS is set if this menu was specified with keymaps;
in that case, we return a list containing the chosen item's value
and perhaps also the pane's prefix.
TITLE is the specified menu title.
(We return nil on failure, but the value doesn't actually matter.) */
Lisp_Object
-w32_menu_show (struct frame *f, int x, int y, int for_click, int keymaps,
+w32_menu_show (struct frame *f, int x, int y, int menuflags,
Lisp_Object title, const char **error)
{
int i;
/* 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 = make_widget_value ("menu", NULL, true, Qnil);
wv->button_type = BUTTON_TYPE_NONE;
- wv->help = Qnil;
first_wv = wv;
first_pane = 1;
/* If the pane has a meaningful name,
make the pane a top-level menu item
with its items as a submenu beneath it. */
- if (!keymaps && strcmp (pane_string, ""))
+ if (!(menuflags & MENU_KEYMAPS) && strcmp (pane_string, ""))
{
- wv = xmalloc_widget_value ();
+ wv = make_widget_value (pane_string, NULL, true, Qnil);
if (save_wv)
save_wv->next = wv;
else
first_wv->contents = wv;
- wv->name = pane_string;
- if (keymaps && !NILP (prefix))
+ if ((menuflags & MENU_KEYMAPS) && !NILP (prefix))
wv->name++;
- wv->value = 0;
- wv->enabled = 1;
wv->button_type = BUTTON_TYPE_NONE;
- wv->help = Qnil;
save_wv = wv;
prev_wv = 0;
}
ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);
}
- wv = xmalloc_widget_value ();
+ wv = make_widget_value (SSDATA (item_name), NULL, !NILP (enable),
+ STRINGP (help) ? help : Qnil);
if (prev_wv)
prev_wv->next = wv;
else
save_wv->contents = wv;
- wv->name = SSDATA (item_name);
if (!NILP (descrip))
wv->key = SSDATA (descrip);
- wv->value = 0;
/* Use the contents index as call_data, since we are
restricted to 16-bits. */
wv->call_data = !NILP (def) ? (void *) (EMACS_INT) i : 0;
- wv->enabled = !NILP (enable);
if (NILP (type))
wv->button_type = BUTTON_TYPE_NONE;
wv->selected = !NILP (selected);
- if (!STRINGP (help))
- help = Qnil;
-
- wv->help = help;
-
prev_wv = wv;
i += MENU_ITEMS_ITEM_LENGTH;
/* Deal with the title, if it is non-nil. */
if (!NILP (title))
{
- widget_value *wv_title = xmalloc_widget_value ();
- widget_value *wv_sep = xmalloc_widget_value ();
+ widget_value *wv_title;
+ widget_value *wv_sep = make_widget_value ("--", NULL, false, Qnil);
/* 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;
if (unicode_append_menu)
title = ENCODE_UTF_8 (title);
else if (STRING_MULTIBYTE (title))
title = ENCODE_SYSTEM (title);
- wv_title->name = SSDATA (title);
- wv_title->enabled = TRUE;
+ wv_title = make_widget_value (SSDATA (title), NULL, true, Qnil);
wv_title->title = TRUE;
wv_title->button_type = BUTTON_TYPE_NONE;
- wv_title->help = Qnil;
wv_title->next = wv_sep;
first_wv->contents = wv_title;
}
i += 1;
else
{
- entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
+ entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
if (menu_item_selection == i)
{
- if (keymaps != 0)
+ if (menuflags & MENU_KEYMAPS)
{
int j;
}
}
}
- else if (!for_click)
+ else if (!(menuflags & MENU_FOR_CLICK))
{
unblock_input ();
/* Make "Cancel" equivalent to C-g. */
"button6", "button7", "button8", "button9", "button10" };
static Lisp_Object
-w32_dialog_show (struct frame *f, int keymaps,
- Lisp_Object title, Lisp_Object header,
- char **error)
+w32_dialog_show (struct frame *f, Lisp_Object title,
+ Lisp_Object header, char **error)
{
int i, nb_buttons = 0;
char dialog_name[6];
/* Create a tree of widget_value objects
representing the text label and buttons. */
{
- Lisp_Object pane_name, prefix;
+ Lisp_Object pane_name;
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)
? "" : SSDATA (pane_name));
- prev_wv = xmalloc_widget_value ();
- prev_wv->value = pane_string;
- if (keymaps && !NILP (prefix))
- prev_wv->name++;
- prev_wv->enabled = 1;
- prev_wv->name = "message";
- prev_wv->help = Qnil;
+ prev_wv = make_widget_value ("message", pane_string, true, Qnil);
first_wv = prev_wv;
/* Loop over all panes and items, filling in the tree. */
return Qnil;
}
- wv = xmalloc_widget_value ();
+ wv = make_widget_value (button_names[nb_buttons],
+ SSDATA (item_name),
+ !NILP (enable), Qnil);
prev_wv->next = wv;
- wv->name = (char *) button_names[nb_buttons];
if (!NILP (descrip))
wv->key = SSDATA (descrip);
- wv->value = SSDATA (item_name);
wv->call_data = aref_addr (menu_items, i);
- wv->enabled = !NILP (enable);
- wv->help = Qnil;
prev_wv = wv;
if (! boundary_seen)
if (! boundary_seen)
left_count = nb_buttons - nb_buttons / 2;
- wv = xmalloc_widget_value ();
- wv->name = dialog_name;
- wv->help = Qnil;
+ wv = make_widget_value (dialog_name, NULL, false, Qnil);
/* Frame title: 'Q' = Question, 'I' = Information.
Can also have 'E' = Error if, one day, we want
the proper value. */
if (menu_item_selection != 0)
{
- Lisp_Object prefix;
-
- prefix = Qnil;
i = 0;
while (i < menu_items_used)
{
Lisp_Object entry;
if (EQ (AREF (menu_items, i), Qt))
- {
- prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
- i += MENU_ITEMS_PANE_LENGTH;
- }
+ i += MENU_ITEMS_PANE_LENGTH;
else
{
- entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
+ entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
if (menu_item_selection == i)
- {
- if (keymaps != 0)
- {
- entry = Fcons (entry, Qnil);
- if (!NILP (prefix))
- entry = Fcons (prefix, entry);
- }
- return entry;
- }
+ return entry;
i += MENU_ITEMS_ITEM_LENGTH;
}
}
void
syms_of_w32menu (void)
{
+#include "w32menu.x"
+
globals_of_w32menu ();
current_popup_menu = NULL;
DEFSYM (Qdebug_on_next_call, "debug-on-next-call");
-
- defsubr (&Smenu_or_popup_active_p);
+ DEFSYM (Qunsupported__w32_dialog, "unsupported--w32-dialog");
}
/*