/* Menu support for GNU Emacs on the Microsoft W32 API.
Copyright (C) 1986, 1988, 1993, 1994, 1996, 1998, 1999, 2001, 2002,
- 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2003, 2004, 2005, 2006, 2007, 2008
+ Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Emacs is distributed in the hope that it will be useful,
Boston, MA 02110-1301, USA. */
#include <config.h>
-#include <signal.h>
+#include <signal.h>
#include <stdio.h>
+#include <mbstring.h>
+
#include "lisp.h"
-#include "termhooks.h"
#include "keyboard.h"
#include "keymap.h"
#include "frame.h"
+#include "termhooks.h"
#include "window.h"
#include "blockinput.h"
#include "buffer.h"
static void
grow_menu_items ()
{
- Lisp_Object old;
- int old_size = menu_items_allocated;
- old = menu_items;
-
menu_items_allocated *= 2;
- menu_items = Fmake_vector (make_number (menu_items_allocated), Qnil);
- bcopy (XVECTOR (old)->contents, XVECTOR (menu_items)->contents,
- old_size * sizeof (Lisp_Object));
+ menu_items = larger_vector (menu_items, menu_items_allocated, Qnil);
}
/* Begin a submenu. */
init_menu_items ();
- for (tail = menu; !NILP (tail); tail = Fcdr (tail))
+ for (tail = menu; CONSP (tail); tail = XCDR (tail))
{
Lisp_Object elt, pane_name, pane_data;
- elt = Fcar (tail);
+ elt = XCAR (tail);
pane_name = Fcar (elt);
CHECK_STRING (pane_name);
push_menu_pane (pane_name, Qnil);
{
Lisp_Object tail, item, item1;
- for (tail = pane; !NILP (tail); tail = Fcdr (tail))
+ for (tail = pane; CONSP (tail); tail = XCDR (tail))
{
- item = Fcar (tail);
+ item = XCAR (tail);
if (STRINGP (item))
push_menu_item (item, Qnil, Qnil, Qt, Qnil, Qnil, Qnil, Qnil);
else if (NILP (item))
enum scroll_bar_part part;
unsigned long time;
- if (mouse_position_hook)
- (*mouse_position_hook) (&new_f, 1, &bar_window,
+ if (FRAME_TERMINAL (new_f)->mouse_position_hook)
+ (*FRAME_TERMINAL (new_f)->mouse_position_hook) (&new_f, 1, &bar_window,
&part, &x, &y, &time);
if (new_f != 0)
XSETFRAME (window, new_f);
/* Free the owner-drawn and help-echo menu strings. */
w32_free_menu_strings (FRAME_W32_WINDOW (f));
+ f->output_data.w32->menubar_active = 0;
/* Find the selected item, and its pane, to return
the proper value. */
add_menu_item (HMENU menu, widget_value *wv, HMENU item)
{
UINT fuFlags;
- char *out_string;
+ char *out_string, *p, *q;
int return_value;
+ size_t nlen, orig_len;
if (name_is_separator (wv->name))
{
else
out_string = wv->name;
+ /* Quote any special characters within the menu item's text and
+ key binding. */
+ nlen = orig_len = strlen (out_string);
+ if (unicode_append_menu)
+ {
+ /* With UTF-8, & cannot be part of a multibyte character. */
+ for (p = out_string; *p; p++)
+ {
+ if (*p == '&')
+ nlen++;
+ }
+ }
+ else
+ {
+ /* If encoded with the system codepage, use multibyte string
+ functions in case of multibyte characters that contain '&'. */
+ for (p = out_string; *p; p = _mbsinc (p))
+ {
+ if (_mbsnextc (p) == '&')
+ nlen++;
+ }
+ }
+
+ if (nlen > orig_len)
+ {
+ p = out_string;
+ out_string = alloca (nlen + 1);
+ q = out_string;
+ while (*p)
+ {
+ if (unicode_append_menu)
+ {
+ if (*p == '&')
+ *q++ = *p;
+ *q++ = *p++;
+ }
+ else
+ {
+ if (_mbsnextc (p) == '&')
+ {
+ _mbsncpy (q, p, 1);
+ q = _mbsinc (q);
+ }
+ _mbsncpy (q, p, 1);
+ p = _mbsinc (p);
+ q = _mbsinc (q);
+ }
+ }
+ *q = '\0';
+ }
+
if (item != NULL)
fuFlags = MF_POPUP;
else if (wv->title || wv->call_data == 0)