X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/ef0f0304040ee5e0ba503baa77109c99ce54e367..b46a6a83b3c30d34aa6b80633394c74e6145291c:/src/w32menu.c diff --git a/src/w32menu.c b/src/w32menu.c index 98b053a9e2..09484d74b7 100644 --- a/src/w32menu.c +++ b/src/w32menu.c @@ -1,5 +1,5 @@ -/* 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. @@ -31,6 +31,7 @@ along with GNU Emacs. If not, see . */ #include "termhooks.h" #include "window.h" #include "blockinput.h" +#include "character.h" #include "buffer.h" #include "charset.h" #include "coding.h" @@ -48,6 +49,8 @@ along with GNU Emacs. If not, see . */ #include "dispextern.h" +#include "w32heap.h" /* for osinfo_cache */ + #undef HAVE_DIALOGS /* TODO: Implement native dialogs. */ #ifndef TRUE @@ -159,13 +162,12 @@ otherwise it is "Question". */) } 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) */ } } @@ -1173,18 +1175,23 @@ w32_dialog_show (FRAME_PTR f, int keymaps, 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; @@ -1197,7 +1204,10 @@ is_simple_dialog (Lisp_Object contents) 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; @@ -1219,10 +1229,11 @@ simple_dialog_show (FRAME_PTR f, Lisp_Object contents, Lisp_Object header) 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)) { @@ -1232,7 +1243,7 @@ simple_dialog_show (FRAME_PTR f, Lisp_Object contents, Lisp_Object header) 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 @@ -1252,6 +1263,7 @@ simple_dialog_show (FRAME_PTR f, Lisp_Object contents, Lisp_Object header) } answer = unicode_message_box (FRAME_W32_WINDOW (f), text, title, type); + SAFE_FREE (); } else { @@ -1358,6 +1370,7 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item) char *out_string, *p, *q; int return_value; size_t nlen, orig_len; + USE_SAFE_ALLOCA; if (menu_separator_name_p (wv->name)) { @@ -1373,7 +1386,8 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item) 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); @@ -1407,7 +1421,7 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item) if (nlen > orig_len) { p = out_string; - out_string = alloca (nlen + 1); + SAFE_ALLOCA (out_string, char *, nlen + 1); q = out_string; while (*p) { @@ -1443,7 +1457,7 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item) 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; } @@ -1467,7 +1481,7 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item) 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, @@ -1476,7 +1490,7 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item) 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 @@ -1486,8 +1500,11 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item) 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)) @@ -1516,11 +1533,14 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item) 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 @@ -1536,6 +1556,7 @@ add_menu_item (HMENU menu, widget_value *wv, HMENU item) FALSE, &info); } } + SAFE_FREE (); return return_value; } @@ -1594,12 +1615,7 @@ w32_menu_display_help (HWND owner, HMENU menu, UINT item, UINT flags) 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