-/* Menu support for GNU Emacs on the Microsoft W32 API.
- Copyright (C) 1986, 1988, 1993-1994, 1996, 1998-1999, 2001-2011
+/* Menu support for GNU Emacs on the Microsoft Windows API.
+ Copyright (C) 1986, 1988, 1993-1994, 1996, 1998-1999, 2001-2012
Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include "termhooks.h"
#include "window.h"
#include "blockinput.h"
+#include "character.h"
#include "buffer.h"
#include "charset.h"
#include "coding.h"
#include "dispextern.h"
+#include "w32heap.h" /* for osinfo_cache */
+
#undef HAVE_DIALOGS /* TODO: Implement native dialogs. */
#ifndef TRUE
}
else if (CONSP (position))
{
- Lisp_Object tem;
- tem = Fcar (position);
+ Lisp_Object tem = XCAR (position);
if (CONSP (tem))
- window = Fcar (Fcdr (position));
+ window = Fcar (XCDR (position));
else
{
- tem = Fcar (Fcdr (position)); /* EVENT_START (position) */
+ tem = Fcar (XCDR (position)); /* EVENT_START (position) */
window = Fcar (tem); /* POSN_WINDOW (tem) */
}
}
return;
entry = Qnil;
subprefix_stack = (Lisp_Object *) alloca (f->menu_bar_items_used * sizeof (Lisp_Object));
- vector = f->menu_bar_vector;
+ vector = FVAR (f, menu_bar_vector);
prefix = Qnil;
i = 0;
while (i < f->menu_bar_items_used)
if (! menubar_widget)
previous_menu_items_used = 0;
- buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer;
+ buffer = WVAR (XWINDOW (FRAME_SELECTED_WINDOW (f)), buffer);
specbind (Qinhibit_quit, Qt);
/* Don't let the debugger step into this code
because it is not reentrant. */
/* Save the frame's previous menu bar contents data. */
if (previous_menu_items_used)
- memcpy (previous_items, XVECTOR (f->menu_bar_vector)->contents,
+ memcpy (previous_items, XVECTOR (FVAR (f, menu_bar_vector))->contents,
previous_menu_items_used * sizeof (Lisp_Object));
/* Fill in menu_items with the current menu bar contents.
This can evaluate Lisp code. */
save_menu_items ();
- menu_items = f->menu_bar_vector;
+ menu_items = FVAR (f, menu_bar_vector);
menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
submenu_start = (int *) alloca (ASIZE (items) * sizeof (int));
submenu_end = (int *) alloca (ASIZE (items) * sizeof (int));
return;
}
- f->menu_bar_vector = menu_items;
+ FVAR (f, menu_bar_vector) = menu_items;
f->menu_bar_items_used = menu_items_used;
/* This undoes save_menu_items. */
static int
is_simple_dialog (Lisp_Object contents)
{
- Lisp_Object options = XCDR (contents);
+ Lisp_Object options;
Lisp_Object name, yes, no, other;
+ if (!CONSP (contents))
+ return 0;
+ options = XCDR (contents);
+
yes = build_string ("Yes");
no = build_string ("No");
if (!CONSP (options))
return 0;
- name = XCAR (XCAR (options));
- if (!CONSP (options))
+ name = XCAR (options);
+ if (!CONSP (name))
return 0;
+ name = XCAR (name);
if (!NILP (Fstring_equal (name, yes)))
other = no;
if (!CONSP (options))
return 0;
- name = XCAR (XCAR (options));
+ name = XCAR (options);
+ if (!CONSP (name))
+ return 0;
+ name = XCAR (name);
if (NILP (Fstring_equal (name, other)))
return 0;
is_simple_dialog, we don't need to worry about checking contents
to see what type of dialog to use. */
- /* Use unicode if possible, so any language can be displayed. */
+ /* Use Unicode if possible, so any language can be displayed. */
if (unicode_message_box)
{
WCHAR *text, *title;
+ USE_SAFE_ALLOCA;
if (STRINGP (temp))
{
one utf16 word, so we cannot simply use the character
length of temp. */
int utf8_len = strlen (utf8_text);
- text = alloca ((utf8_len + 1) * sizeof (WCHAR));
+ SAFE_ALLOCA (text, WCHAR *, (utf8_len + 1) * sizeof (WCHAR));
utf8to16 (utf8_text, utf8_len, text);
}
else
}
answer = unicode_message_box (FRAME_W32_WINDOW (f), text, title, type);
+ SAFE_FREE ();
}
else
{
char *out_string, *p, *q;
int return_value;
size_t nlen, orig_len;
+ USE_SAFE_ALLOCA;
if (menu_separator_name_p (wv->name))
{
if (wv->key != NULL)
{
- out_string = alloca (strlen (wv->name) + strlen (wv->key) + 2);
+ SAFE_ALLOCA (out_string, char *,
+ strlen (wv->name) + strlen (wv->key) + 2);
strcpy (out_string, wv->name);
strcat (out_string, "\t");
strcat (out_string, wv->key);
if (nlen > orig_len)
{
p = out_string;
- out_string = alloca (nlen + 1);
+ SAFE_ALLOCA (out_string, char *, nlen + 1);
q = out_string;
while (*p)
{
out_string = (char *) local_alloc (strlen (wv->name) + 1);
strcpy (out_string, wv->name);
#ifdef MENU_DEBUG
- DebPrint ("Menu: allocing %ld for owner-draw", out_string);
+ DebPrint ("Menu: allocating %ld for owner-draw", out_string);
#endif
fuFlags = MF_OWNERDRAW | MF_DISABLED;
}
if (fuFlags & MF_OWNERDRAW)
utf16_string = local_alloc ((utf8_len + 1) * sizeof (WCHAR));
else
- utf16_string = alloca ((utf8_len + 1) * sizeof (WCHAR));
+ SAFE_ALLOCA (utf16_string, WCHAR *, (utf8_len + 1) * sizeof (WCHAR));
utf8to16 (out_string, utf8_len, utf16_string);
return_value = unicode_append_menu (menu, fuFlags,
utf16_string);
if (!return_value)
{
- /* On W9x/ME, unicode menus are not supported, though AppendMenuW
+ /* On W9x/ME, Unicode menus are not supported, though AppendMenuW
apparently does exist at least in some cases and appears to be
stubbed out to do nothing. out_string is UTF-8, but since
our standard menus are in English and this is only going to
AppendMenu (menu, fuFlags,
item != NULL ? (UINT) item: (UINT) wv->call_data,
out_string);
- /* Don't use unicode menus in future. */
- unicode_append_menu = NULL;
+ /* Don't use Unicode menus in future, unless this is Windows
+ NT or later, where a failure of AppendMenuW does NOT mean
+ Unicode menus are unsupported. */
+ if (osinfo_cache.dwPlatformId != VER_PLATFORM_WIN32_NT)
+ unicode_append_menu = NULL;
}
if (unicode_append_menu && (fuFlags & MF_OWNERDRAW))
until it is ready to be displayed, since GC can happen while
menus are active. */
if (!NILP (wv->help))
-#ifdef USE_LISP_UNION_TYPE
- info.dwItemData = (DWORD) (wv->help).i;
-#else
- info.dwItemData = (DWORD) (wv->help);
-#endif
+ {
+ /* As of Jul-2012, w32api headers say that dwItemData
+ has DWORD type, but that's a bug: it should actually
+ be ULONG_PTR, which is correct for 32-bit and 64-bit
+ Windows alike. MSVC headers get it right; hopefully,
+ MinGW headers will, too. */
+ info.dwItemData = (ULONG_PTR) XLI (wv->help);
+ }
if (wv->button_type == BUTTON_TYPE_RADIO)
{
/* CheckMenuRadioItem allows us to differentiate TOGGLE and
FALSE, &info);
}
}
+ SAFE_FREE ();
return return_value;
}
info.fMask = MIIM_DATA;
get_menu_item_info (menu, item, FALSE, &info);
-#ifdef USE_LISP_UNION_TYPE
- help = info.dwItemData ? (Lisp_Object) ((EMACS_INT) info.dwItemData)
- : Qnil;
-#else
- help = info.dwItemData ? (Lisp_Object) info.dwItemData : Qnil;
-#endif
+ help = info.dwItemData ? XIL (info.dwItemData) : Qnil;
}
/* Store the help echo in the keyboard buffer as the X toolkit