root/src/w32menu.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. w32_popup_dialog
  2. w32_activate_menubar
  3. menubar_selection_callback
  4. set_frame_menubar
  5. initialize_frame_menubar
  6. free_frame_menubar
  7. w32_menu_show
  8. w32_dialog_show
  9. is_simple_dialog
  10. simple_dialog_show
  11. utf8to16
  12. add_menu_item
  13. fill_in_menu
  14. w32_menu_display_help
  15. w32_free_submenu_strings
  16. w32_free_menu_strings
  17. DEFUN
  18. syms_of_w32menu
  19. globals_of_w32menu

     1 /* Menu support for GNU Emacs on the Microsoft Windows API.
     2    Copyright (C) 1986, 1988, 1993-1994, 1996, 1998-1999, 2001-2023 Free
     3    Software Foundation, Inc.
     4 
     5 This file is part of GNU Emacs.
     6 
     7 GNU Emacs is free software: you can redistribute it and/or modify
     8 it under the terms of the GNU General Public License as published by
     9 the Free Software Foundation, either version 3 of the License, or (at
    10 your option) any later version.
    11 
    12 GNU Emacs is distributed in the hope that it will be useful,
    13 but WITHOUT ANY WARRANTY; without even the implied warranty of
    14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15 GNU General Public License for more details.
    16 
    17 You should have received a copy of the GNU General Public License
    18 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
    19 
    20 #include <config.h>
    21 
    22 #include <signal.h>
    23 #include <stdio.h>
    24 #include <setjmp.h>
    25 
    26 #include "lisp.h"
    27 #include "keyboard.h"
    28 #include "frame.h"
    29 #include "blockinput.h"
    30 #include "buffer.h"
    31 #include "coding.h"     /* for ENCODE_SYSTEM */
    32 #include "menu.h"
    33 #include "pdumper.h"
    34 
    35 /* This may include sys/types.h, and that somehow loses
    36    if this is not done before the other system files.  */
    37 #include "w32term.h"
    38 
    39 /* Cygwin does not support the multibyte string functions declared in
    40  * mbstring.h below --- but that's okay: because Cygwin is
    41  * UNICODE-only, we don't need to use these functions anyway.  */
    42 
    43 #ifndef NTGUI_UNICODE
    44 #include <mbstring.h>
    45 #endif /* !NTGUI_UNICODE */
    46 
    47 /* Load sys/types.h if not already loaded.
    48    In some systems loading it twice is suicidal.  */
    49 #ifndef makedev
    50 #include <sys/types.h>
    51 #endif
    52 
    53 #include "w32common.h"  /* for osinfo_cache */
    54 
    55 #undef HAVE_DIALOGS /* TODO: Implement native dialogs.  */
    56 
    57 #ifndef TRUE
    58 #define TRUE 1
    59 #define FALSE 0
    60 #endif /* no TRUE */
    61 
    62 HMENU current_popup_menu;
    63 
    64 typedef BOOL (WINAPI * GetMenuItemInfoA_Proc) (
    65     IN HMENU,
    66     IN UINT,
    67     IN BOOL,
    68     IN OUT LPMENUITEMINFOA);
    69 typedef BOOL (WINAPI * SetMenuItemInfoA_Proc) (
    70     IN HMENU,
    71     IN UINT,
    72     IN BOOL,
    73     IN LPCMENUITEMINFOA);
    74 typedef int (WINAPI * MessageBoxW_Proc) (
    75     IN HWND window,
    76     IN const WCHAR *text,
    77     IN const WCHAR *caption,
    78     IN UINT type);
    79 
    80 #ifdef NTGUI_UNICODE
    81 GetMenuItemInfoA_Proc get_menu_item_info = GetMenuItemInfoA;
    82 SetMenuItemInfoA_Proc set_menu_item_info = SetMenuItemInfoA;
    83 AppendMenuW_Proc unicode_append_menu = AppendMenuW;
    84 MessageBoxW_Proc unicode_message_box = MessageBoxW;
    85 #else /* !NTGUI_UNICODE */
    86 GetMenuItemInfoA_Proc get_menu_item_info = NULL;
    87 SetMenuItemInfoA_Proc set_menu_item_info = NULL;
    88 AppendMenuW_Proc unicode_append_menu = NULL;
    89 MessageBoxW_Proc unicode_message_box = NULL;
    90 #endif /* NTGUI_UNICODE */
    91 
    92 #ifdef HAVE_DIALOGS
    93 static Lisp_Object w32_dialog_show (struct frame *, Lisp_Object, Lisp_Object, char **);
    94 #else
    95 static bool is_simple_dialog (Lisp_Object);
    96 static Lisp_Object simple_dialog_show (struct frame *, Lisp_Object, Lisp_Object);
    97 #endif
    98 
    99 static void utf8to16 (unsigned char *, int, WCHAR *);
   100 static int fill_in_menu (HMENU, widget_value *);
   101 
   102 void w32_free_menu_strings (HWND);
   103 
   104 Lisp_Object
   105 w32_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents)
   106 {
   107 
   108   check_window_system (f);
   109 
   110 #ifndef HAVE_DIALOGS
   111 
   112   /* Handle simple Yes/No choices as MessageBox popups.  */
   113   if (is_simple_dialog (contents))
   114     return simple_dialog_show (f, contents, header);
   115   else
   116     return Qunsupported__w32_dialog;
   117 #else  /* HAVE_DIALOGS */
   118     {
   119       Lisp_Object title;
   120       char *error_name;
   121       Lisp_Object selection;
   122 
   123       /* Decode the dialog items from what was specified.  */
   124       title = Fcar (contents);
   125       CHECK_STRING (title);
   126 
   127       list_of_panes (Fcons (contents, Qnil));
   128 
   129       /* Display them in a dialog box.  */
   130       block_input ();
   131       selection = w32_dialog_show (f, title, header, &error_name);
   132       unblock_input ();
   133 
   134       discard_menu_items ();
   135       FRAME_DISPLAY_INFO (f)->grabbed = 0;
   136 
   137       if (error_name) error (error_name);
   138       return selection;
   139     }
   140 #endif /* HAVE_DIALOGS */
   141 }
   142 
   143 /* Activate the menu bar of frame F.
   144    This is called from keyboard.c when it gets the
   145    MENU_BAR_ACTIVATE_EVENT out of the Emacs event queue.
   146 
   147    To activate the menu bar, we signal to the input thread that it can
   148    return from the WM_INITMENU message, allowing the normal Windows
   149    processing of the menus.
   150 
   151    But first we recompute the menu bar contents (the whole tree).
   152 
   153    This way we can safely execute Lisp code.  */
   154 
   155 void
   156 w32_activate_menubar (struct frame *f)
   157 {
   158   set_frame_menubar (f, true);
   159 
   160   /* Lock out further menubar changes while active.  */
   161   f->output_data.w32->menubar_active = 1;
   162 
   163   /* Signal input thread to return from WM_INITMENU.  */
   164   complete_deferred_msg (FRAME_W32_WINDOW (f), WM_INITMENU, 0);
   165 }
   166 
   167 /* This callback is called from the menu bar pulldown menu
   168    when the user makes a selection.
   169    Figure out what the user chose
   170    and put the appropriate events into the keyboard buffer.  */
   171 void menubar_selection_callback (struct frame *, void *);
   172 
   173 void
   174 menubar_selection_callback (struct frame *f, void * client_data)
   175 {
   176   Lisp_Object prefix, entry;
   177   Lisp_Object vector;
   178   Lisp_Object *subprefix_stack;
   179   int submenu_depth = 0;
   180   int i;
   181 
   182   if (!f)
   183     return;
   184   entry = Qnil;
   185   subprefix_stack = (Lisp_Object *) alloca (f->menu_bar_items_used * word_size);
   186   vector = f->menu_bar_vector;
   187   prefix = Qnil;
   188   i = 0;
   189   while (i < f->menu_bar_items_used)
   190     {
   191       if (NILP (AREF (vector, i)))
   192         {
   193           subprefix_stack[submenu_depth++] = prefix;
   194           prefix = entry;
   195           i++;
   196         }
   197       else if (EQ (AREF (vector, i), Qlambda))
   198         {
   199           prefix = subprefix_stack[--submenu_depth];
   200           i++;
   201         }
   202       else if (EQ (AREF (vector, i), Qt))
   203         {
   204           prefix = AREF (vector, i + MENU_ITEMS_PANE_PREFIX);
   205           i += MENU_ITEMS_PANE_LENGTH;
   206         }
   207       else
   208         {
   209           entry = AREF (vector, i + MENU_ITEMS_ITEM_VALUE);
   210           /* The UINT_PTR cast avoids a warning.  There's no problem
   211              as long as pointers have enough bits to hold small integers.  */
   212           if ((int) (UINT_PTR) client_data == i)
   213             {
   214               int j;
   215               struct input_event buf;
   216               Lisp_Object frame;
   217               EVENT_INIT (buf);
   218 
   219               XSETFRAME (frame, f);
   220               buf.kind = MENU_BAR_EVENT;
   221               buf.frame_or_window = frame;
   222               buf.arg = frame;
   223               kbd_buffer_store_event (&buf);
   224 
   225               for (j = 0; j < submenu_depth; j++)
   226                 if (!NILP (subprefix_stack[j]))
   227                   {
   228                     buf.kind = MENU_BAR_EVENT;
   229                     buf.frame_or_window = frame;
   230                     buf.arg = subprefix_stack[j];
   231                     kbd_buffer_store_event (&buf);
   232                   }
   233 
   234               if (!NILP (prefix))
   235                 {
   236                   buf.kind = MENU_BAR_EVENT;
   237                   buf.frame_or_window = frame;
   238                   buf.arg = prefix;
   239                   kbd_buffer_store_event (&buf);
   240                 }
   241 
   242               buf.kind = MENU_BAR_EVENT;
   243               buf.frame_or_window = frame;
   244               buf.arg = entry;
   245               /* Free memory used by owner-drawn and help-echo strings.  */
   246               w32_free_menu_strings (FRAME_W32_WINDOW (f));
   247               kbd_buffer_store_event (&buf);
   248 
   249               f->output_data.w32->menubar_active = 0;
   250               return;
   251             }
   252           i += MENU_ITEMS_ITEM_LENGTH;
   253         }
   254     }
   255   /* Free memory used by owner-drawn and help-echo strings.  */
   256   w32_free_menu_strings (FRAME_W32_WINDOW (f));
   257   f->output_data.w32->menubar_active = 0;
   258 }
   259 
   260 
   261 /* Set the contents of the menubar widgets of frame F.  */
   262 
   263 void
   264 set_frame_menubar (struct frame *f, bool deep_p)
   265 {
   266   HMENU menubar_widget = f->output_data.w32->menubar_widget;
   267   Lisp_Object items;
   268   widget_value *wv, *first_wv, *prev_wv = 0;
   269   int i, last_i = 0;
   270   int *submenu_start, *submenu_end;
   271   int *submenu_top_level_items, *submenu_n_panes;
   272 
   273   /* We must not change the menubar when actually in use.  */
   274   if (f->output_data.w32->menubar_active)
   275     return;
   276 
   277   XSETFRAME (Vmenu_updating_frame, f);
   278 
   279   if (! menubar_widget)
   280     deep_p = true;
   281 
   282   if (deep_p)
   283     {
   284       /* Make a widget-value tree representing the entire menu trees.  */
   285 
   286       struct buffer *prev = current_buffer;
   287       Lisp_Object buffer;
   288       specpdl_ref specpdl_count = SPECPDL_INDEX ();
   289       int previous_menu_items_used = f->menu_bar_items_used;
   290       Lisp_Object *previous_items
   291         = (Lisp_Object *) alloca (previous_menu_items_used
   292                                   * word_size);
   293 
   294       /* If we are making a new widget, its contents are empty,
   295          do always reinitialize them.  */
   296       if (! menubar_widget)
   297         previous_menu_items_used = 0;
   298 
   299       buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->contents;
   300       specbind (Qinhibit_quit, Qt);
   301       /* Don't let the debugger step into this code
   302          because it is not reentrant.  */
   303       specbind (Qdebug_on_next_call, Qnil);
   304 
   305       record_unwind_save_match_data ();
   306 
   307       if (NILP (Voverriding_local_map_menu_flag))
   308         {
   309           specbind (Qoverriding_terminal_local_map, Qnil);
   310           specbind (Qoverriding_local_map, Qnil);
   311         }
   312 
   313       set_buffer_internal_1 (XBUFFER (buffer));
   314 
   315       /* Run the hooks.  */
   316       safe_run_hooks (Qactivate_menubar_hook);
   317       safe_run_hooks (Qmenu_bar_update_hook);
   318       fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
   319 
   320       items = FRAME_MENU_BAR_ITEMS (f);
   321 
   322       /* Save the frame's previous menu bar contents data.  */
   323       if (previous_menu_items_used)
   324         memcpy (previous_items, XVECTOR (f->menu_bar_vector)->contents,
   325                 previous_menu_items_used * word_size);
   326 
   327       /* Fill in menu_items with the current menu bar contents.
   328          This can evaluate Lisp code.  */
   329       save_menu_items ();
   330 
   331       menu_items = f->menu_bar_vector;
   332       menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
   333       submenu_start = (int *) alloca (ASIZE (items) * sizeof (int));
   334       submenu_end = (int *) alloca (ASIZE (items) * sizeof (int));
   335       submenu_n_panes = (int *) alloca (ASIZE (items) * sizeof (int));
   336       submenu_top_level_items = (int *) alloca (ASIZE (items) * sizeof (int));
   337       init_menu_items ();
   338       for (i = 0; i < ASIZE (items); i += 4)
   339         {
   340           Lisp_Object key, string, maps;
   341 
   342           last_i = i;
   343 
   344           key = AREF (items, i);
   345           string = AREF (items, i + 1);
   346           maps = AREF (items, i + 2);
   347           if (NILP (string))
   348             break;
   349 
   350           submenu_start[i] = menu_items_used;
   351 
   352           menu_items_n_panes = 0;
   353           submenu_top_level_items[i]
   354             = parse_single_submenu (key, string, maps);
   355           submenu_n_panes[i] = menu_items_n_panes;
   356 
   357           submenu_end[i] = menu_items_used;
   358         }
   359 
   360       finish_menu_items ();
   361 
   362       /* Convert menu_items into widget_value trees
   363          to display the menu.  This cannot evaluate Lisp code.  */
   364 
   365       wv = make_widget_value ("menubar", NULL, true, Qnil);
   366       wv->button_type = BUTTON_TYPE_NONE;
   367       first_wv = wv;
   368 
   369       for (i = 0; i < last_i; i += 4)
   370         {
   371           menu_items_n_panes = submenu_n_panes[i];
   372           wv = digest_single_submenu (submenu_start[i], submenu_end[i],
   373                                       submenu_top_level_items[i]);
   374           if (prev_wv)
   375             prev_wv->next = wv;
   376           else
   377             first_wv->contents = wv;
   378           /* Don't set wv->name here; GC during the loop might relocate it.  */
   379           wv->enabled = true;
   380           wv->button_type = BUTTON_TYPE_NONE;
   381           prev_wv = wv;
   382         }
   383 
   384       set_buffer_internal_1 (prev);
   385 
   386       /* If there has been no change in the Lisp-level contents
   387          of the menu bar, skip redisplaying it.  Just exit.  */
   388 
   389       for (i = 0; i < previous_menu_items_used; i++)
   390         if (menu_items_used == i
   391             || (!EQ (previous_items[i], AREF (menu_items, i))))
   392           break;
   393       if (i == menu_items_used && i == previous_menu_items_used && i != 0)
   394         {
   395           free_menubar_widget_value_tree (first_wv);
   396           discard_menu_items ();
   397           unbind_to (specpdl_count, Qnil);
   398           return;
   399         }
   400 
   401       fset_menu_bar_vector (f, menu_items);
   402       f->menu_bar_items_used = menu_items_used;
   403 
   404       /* This undoes save_menu_items.  */
   405       unbind_to (specpdl_count, Qnil);
   406 
   407       /* Now GC cannot happen during the lifetime of the widget_value,
   408          so it's safe to store data from a Lisp_String, as long as
   409          local copies are made when the actual menu is created.
   410          Windows takes care of this for normal string items, but
   411          not for owner-drawn items or additional item-info.  */
   412       wv = first_wv->contents;
   413       for (i = 0; i < ASIZE (items); i += 4)
   414         {
   415           Lisp_Object string;
   416           string = AREF (items, i + 1);
   417           if (NILP (string))
   418             break;
   419           wv->name = SSDATA (string);
   420           update_submenu_strings (wv->contents);
   421           wv = wv->next;
   422         }
   423     }
   424   else
   425     {
   426       /* Make a widget-value tree containing
   427          just the top level menu bar strings.  */
   428 
   429       wv = make_widget_value ("menubar", NULL, true, Qnil);
   430       wv->button_type = BUTTON_TYPE_NONE;
   431       first_wv = wv;
   432 
   433       items = FRAME_MENU_BAR_ITEMS (f);
   434       for (i = 0; i < ASIZE (items); i += 4)
   435         {
   436           Lisp_Object string;
   437 
   438           string = AREF (items, i + 1);
   439           if (NILP (string))
   440             break;
   441 
   442           wv = make_widget_value (SSDATA (string), NULL, true, Qnil);
   443           wv->button_type = BUTTON_TYPE_NONE;
   444           /* This prevents lwlib from assuming this
   445              menu item is really supposed to be empty.  */
   446           /* The EMACS_INT cast avoids a warning.
   447              This value just has to be different from small integers.  */
   448           wv->call_data = (void *) (EMACS_INT) (-1);
   449 
   450           if (prev_wv)
   451             prev_wv->next = wv;
   452           else
   453             first_wv->contents = wv;
   454           prev_wv = wv;
   455         }
   456 
   457       /* Forget what we thought we knew about what is in the
   458          detailed contents of the menu bar menus.
   459          Changing the top level always destroys the contents.  */
   460       f->menu_bar_items_used = 0;
   461     }
   462 
   463   /* Create or update the menu bar widget.  */
   464 
   465   block_input ();
   466 
   467   if (menubar_widget)
   468     {
   469       /* Empty current menubar, rather than creating a fresh one.  */
   470       while (DeleteMenu (menubar_widget, 0, MF_BYPOSITION))
   471         ;
   472     }
   473   else
   474     {
   475       menubar_widget = CreateMenu ();
   476     }
   477   fill_in_menu (menubar_widget, first_wv->contents);
   478 
   479   free_menubar_widget_value_tree (first_wv);
   480 
   481   {
   482     HMENU old_widget = f->output_data.w32->menubar_widget;
   483 
   484     f->output_data.w32->menubar_widget = menubar_widget;
   485     SetMenu (FRAME_W32_WINDOW (f), f->output_data.w32->menubar_widget);
   486     /* Causes flicker when menu bar is updated
   487     DrawMenuBar (FRAME_W32_WINDOW (f)); */
   488 
   489     /* Force the window size to be recomputed so that the frame's text
   490        area remains the same, if menubar has just been created.  */
   491     if (old_widget == NULL)
   492       {
   493         windows_or_buffers_changed = 23;
   494         adjust_frame_size (f, -1, -1, 2, false, Qmenu_bar_lines);
   495       }
   496   }
   497 
   498   unblock_input ();
   499 }
   500 
   501 /* Called from Fx_create_frame to create the initial menubar of a frame
   502    before it is mapped, so that the window is mapped with the menubar already
   503    there instead of us tacking it on later and thrashing the window after it
   504    is visible.  */
   505 
   506 void
   507 initialize_frame_menubar (struct frame *f)
   508 {
   509   /* This function is called before the first chance to redisplay
   510      the frame.  It has to be, so the frame will have the right size.  */
   511   fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
   512   set_frame_menubar (f, true);
   513 }
   514 
   515 /* Get rid of the menu bar of frame F, and free its storage.
   516    This is used when deleting a frame, and when turning off the menu bar.  */
   517 
   518 void
   519 free_frame_menubar (struct frame *f)
   520 {
   521   block_input ();
   522 
   523   {
   524     HMENU old = GetMenu (FRAME_W32_WINDOW (f));
   525     SetMenu (FRAME_W32_WINDOW (f), NULL);
   526     f->output_data.w32->menubar_widget = NULL;
   527     DestroyMenu (old);
   528   }
   529 
   530   unblock_input ();
   531 }
   532 
   533 
   534 /* w32_menu_show actually displays a menu using the panes and items in
   535    menu_items and returns the value selected from it; we assume input
   536    is blocked by the caller.  */
   537 
   538 /* F is the frame the menu is for.
   539    X and Y are the frame-relative specified position,
   540    relative to the inside upper left corner of the frame F.
   541    Bitfield MENUFLAGS bits are:
   542    MENU_FOR_CLICK is set if this menu was invoked for a mouse click.
   543    MENU_KEYMAPS is set if this menu was specified with keymaps;
   544     in that case, we return a list containing the chosen item's value
   545     and perhaps also the pane's prefix.
   546    TITLE is the specified menu title.
   547    ERROR is a place to store an error message string in case of failure.
   548    (We return nil on failure, but the value doesn't actually matter.)  */
   549 
   550 Lisp_Object
   551 w32_menu_show (struct frame *f, int x, int y, int menuflags,
   552                Lisp_Object title, const char **error)
   553 {
   554   int i;
   555   int menu_item_selection;
   556   HMENU menu;
   557   POINT pos;
   558   widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0;
   559   widget_value **submenu_stack;
   560   Lisp_Object *subprefix_stack;
   561   int submenu_depth = 0;
   562   bool first_pane;
   563 
   564   *error = NULL;
   565 
   566   if (menu_items_n_panes == 0)
   567     return Qnil;
   568 
   569   if (menu_items_used <= MENU_ITEMS_PANE_LENGTH)
   570     {
   571       *error = "Empty menu";
   572       return Qnil;
   573     }
   574 
   575   USE_SAFE_ALLOCA;
   576 
   577   submenu_stack = SAFE_ALLOCA (menu_items_used * sizeof (widget_value *));
   578   subprefix_stack = SAFE_ALLOCA (menu_items_used * word_size);
   579 
   580   block_input ();
   581 
   582   /* Create a tree of widget_value objects
   583      representing the panes and their items.  */
   584   wv = make_widget_value ("menu", NULL, true, Qnil);
   585   wv->button_type = BUTTON_TYPE_NONE;
   586   first_wv = wv;
   587   first_pane = true;
   588 
   589   /* Loop over all panes and items, filling in the tree.  */
   590   i = 0;
   591   while (i < menu_items_used)
   592     {
   593       if (NILP (AREF (menu_items, i)))
   594         {
   595           submenu_stack[submenu_depth++] = save_wv;
   596           save_wv = prev_wv;
   597           prev_wv = 0;
   598           first_pane = false;
   599           i++;
   600         }
   601       else if (EQ (AREF (menu_items, i), Qlambda))
   602         {
   603           prev_wv = save_wv;
   604           save_wv = submenu_stack[--submenu_depth];
   605           first_pane = false;
   606           i++;
   607         }
   608       else if (EQ (AREF (menu_items, i), Qt)
   609                && submenu_depth != 0)
   610         i += MENU_ITEMS_PANE_LENGTH;
   611       /* Ignore a nil in the item list.
   612          It's meaningful only for dialog boxes.  */
   613       else if (EQ (AREF (menu_items, i), Qquote))
   614         i += 1;
   615       else if (EQ (AREF (menu_items, i), Qt))
   616         {
   617           /* Create a new pane.  */
   618           Lisp_Object pane_name, prefix;
   619           const char *pane_string;
   620           pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
   621           prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
   622 
   623           if (STRINGP (pane_name))
   624             {
   625               if (unicode_append_menu)
   626                 pane_name = ENCODE_UTF_8 (pane_name);
   627               else if (STRING_MULTIBYTE (pane_name))
   628                 pane_name = ENCODE_SYSTEM (pane_name);
   629 
   630               ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);
   631             }
   632 
   633           pane_string = (NILP (pane_name)
   634                          ? "" : SSDATA (pane_name));
   635           /* If there is just one top-level pane, put all its items directly
   636              under the top-level menu.  */
   637           if (menu_items_n_panes == 1)
   638             pane_string = "";
   639 
   640           /* If the pane has a meaningful name,
   641              make the pane a top-level menu item
   642              with its items as a submenu beneath it.  */
   643           if (!(menuflags & MENU_KEYMAPS) && strcmp (pane_string, ""))
   644             {
   645               wv = make_widget_value (pane_string, NULL, true, Qnil);
   646               if (save_wv)
   647                 save_wv->next = wv;
   648               else
   649                 first_wv->contents = wv;
   650               if ((menuflags & MENU_KEYMAPS) && !NILP (prefix))
   651                 wv->name++;
   652               wv->button_type = BUTTON_TYPE_NONE;
   653               save_wv = wv;
   654               prev_wv = 0;
   655             }
   656           else if (first_pane)
   657             {
   658               save_wv = wv;
   659               prev_wv = 0;
   660             }
   661           first_pane = false;
   662           i += MENU_ITEMS_PANE_LENGTH;
   663         }
   664       else
   665         {
   666           /* Create a new item within current pane.  */
   667           Lisp_Object item_name, enable, descrip, def, type, selected, help;
   668 
   669           item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
   670           enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
   671           descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
   672           def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION);
   673           type = AREF (menu_items, i + MENU_ITEMS_ITEM_TYPE);
   674           selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED);
   675           help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
   676 
   677           if (STRINGP (item_name))
   678             {
   679               if (unicode_append_menu)
   680                 item_name = ENCODE_UTF_8 (item_name);
   681               else if (STRING_MULTIBYTE (item_name))
   682                 item_name = ENCODE_SYSTEM (item_name);
   683 
   684               ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name);
   685             }
   686 
   687           if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
   688             {
   689               descrip = ENCODE_SYSTEM (descrip);
   690               ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);
   691             }
   692 
   693           wv = make_widget_value (SSDATA (item_name), NULL, !NILP (enable),
   694                                   STRINGP (help) ? help : Qnil);
   695           if (prev_wv)
   696             prev_wv->next = wv;
   697           else
   698             save_wv->contents = wv;
   699           if (!NILP (descrip))
   700             wv->key = SSDATA (descrip);
   701           /* Use the contents index as call_data, since we are
   702              restricted to 16-bits.  */
   703           wv->call_data = !NILP (def) ? (void *) (UINT_PTR) i : 0;
   704 
   705           if (NILP (type))
   706             wv->button_type = BUTTON_TYPE_NONE;
   707           else if (EQ (type, QCtoggle))
   708             wv->button_type = BUTTON_TYPE_TOGGLE;
   709           else if (EQ (type, QCradio))
   710             wv->button_type = BUTTON_TYPE_RADIO;
   711           else
   712             emacs_abort ();
   713 
   714           wv->selected = !NILP (selected);
   715 
   716           prev_wv = wv;
   717 
   718           i += MENU_ITEMS_ITEM_LENGTH;
   719         }
   720     }
   721 
   722   /* Deal with the title, if it is non-nil.  */
   723   if (!NILP (title))
   724     {
   725       widget_value *wv_title;
   726       widget_value *wv_sep = make_widget_value ("--", NULL, false, Qnil);
   727 
   728       /* Maybe replace this separator with a bitmap or owner-draw item
   729          so that it looks better.  Having two separators looks odd.  */
   730       wv_sep->next = first_wv->contents;
   731 
   732       if (unicode_append_menu)
   733         title = ENCODE_UTF_8 (title);
   734       else if (STRING_MULTIBYTE (title))
   735         title = ENCODE_SYSTEM (title);
   736 
   737       wv_title = make_widget_value (SSDATA (title), NULL, true, Qnil);
   738       wv_title->title = TRUE;
   739       wv_title->button_type = BUTTON_TYPE_NONE;
   740       wv_title->next = wv_sep;
   741       first_wv->contents = wv_title;
   742     }
   743 
   744   /* No selection has been chosen yet.  */
   745   menu_item_selection = 0;
   746 
   747   /* Actually create the menu.  */
   748   current_popup_menu = menu = CreatePopupMenu ();
   749   fill_in_menu (menu, first_wv->contents);
   750 
   751   /* Adjust coordinates to be root-window-relative.  */
   752   pos.x = x;
   753   pos.y = y;
   754   ClientToScreen (FRAME_W32_WINDOW (f), &pos);
   755 
   756   /* Display the menu.  */
   757   menu_item_selection = SendMessage (FRAME_W32_WINDOW (f),
   758                                      WM_EMACS_TRACKPOPUPMENU,
   759                                      (WPARAM)menu, (LPARAM)&pos);
   760 
   761   /* Clean up extraneous mouse events which might have been generated
   762      during the call. */
   763   discard_mouse_events ();
   764   FRAME_DISPLAY_INFO (f)->grabbed = 0;
   765 
   766   /* Free the widget_value objects we used to specify the contents.  */
   767   free_menubar_widget_value_tree (first_wv);
   768 
   769   DestroyMenu (menu);
   770 
   771   /* Free the owner-drawn and help-echo menu strings.  */
   772   w32_free_menu_strings (FRAME_W32_WINDOW (f));
   773   f->output_data.w32->menubar_active = 0;
   774 
   775   /* Find the selected item, and its pane, to return
   776      the proper value.  */
   777   if (menu_item_selection != 0)
   778     {
   779       Lisp_Object prefix, entry;
   780 
   781       prefix = entry = Qnil;
   782       i = 0;
   783       while (i < menu_items_used)
   784         {
   785           if (NILP (AREF (menu_items, i)))
   786             {
   787               subprefix_stack[submenu_depth++] = prefix;
   788               prefix = entry;
   789               i++;
   790             }
   791           else if (EQ (AREF (menu_items, i), Qlambda))
   792             {
   793               prefix = subprefix_stack[--submenu_depth];
   794               i++;
   795             }
   796           else if (EQ (AREF (menu_items, i), Qt))
   797             {
   798               prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
   799               i += MENU_ITEMS_PANE_LENGTH;
   800             }
   801           /* Ignore a nil in the item list.
   802              It's meaningful only for dialog boxes.  */
   803           else if (EQ (AREF (menu_items, i), Qquote))
   804             i += 1;
   805           else
   806             {
   807               entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
   808               if (menu_item_selection == i)
   809                 {
   810                   if (menuflags & MENU_KEYMAPS)
   811                     {
   812                       int j;
   813 
   814                       entry = Fcons (entry, Qnil);
   815                       if (!NILP (prefix))
   816                         entry = Fcons (prefix, entry);
   817                       for (j = submenu_depth - 1; j >= 0; j--)
   818                         if (!NILP (subprefix_stack[j]))
   819                           entry = Fcons (subprefix_stack[j], entry);
   820                     }
   821                   unblock_input ();
   822                   SAFE_FREE ();
   823                   return entry;
   824                 }
   825               i += MENU_ITEMS_ITEM_LENGTH;
   826             }
   827         }
   828     }
   829   else if (!(menuflags & MENU_FOR_CLICK))
   830     {
   831       unblock_input ();
   832       /* Make "Cancel" equivalent to C-g.  */
   833       quit ();
   834     }
   835 
   836   unblock_input ();
   837   SAFE_FREE ();
   838   return Qnil;
   839 }
   840 
   841 
   842 #ifdef HAVE_DIALOGS
   843 /* TODO: On Windows, there are two ways of defining a dialog.
   844 
   845    1. Create a predefined dialog resource and include it in nt/emacs.rc.
   846       Using this method, we could then set the titles and make unneeded
   847       buttons invisible before displaying the dialog.  Everything would
   848       be a fixed size though, so there is a risk that text does not
   849       fit on a button.
   850    2. Create the dialog template in memory on the fly.  This allows us
   851       to size the dialog and buttons dynamically, probably giving more
   852       natural looking results for dialogs with few buttons, and eliminating
   853       the problem of text overflowing the buttons.  But the API for this is
   854       quite complex - structures have to be allocated in particular ways,
   855       text content is tacked onto the end of structures in variable length
   856       arrays with further structures tacked on after these, there are
   857       certain alignment requirements for all this, and we have to
   858       measure all the text and convert to "dialog coordinates" to figure
   859       out how big to make everything.
   860 
   861       For now, we'll just stick with menus for dialogs that are more
   862       complicated than simple yes/no type questions for which we can use
   863       the MessageBox function.
   864 */
   865 
   866 static char * button_names [] = {
   867   "button1", "button2", "button3", "button4", "button5",
   868   "button6", "button7", "button8", "button9", "button10" };
   869 
   870 static Lisp_Object
   871 w32_dialog_show (struct frame *f, Lisp_Object title,
   872                  Lisp_Object header, char **error)
   873 {
   874   int i, nb_buttons = 0;
   875   char dialog_name[6];
   876   int menu_item_selection;
   877 
   878   widget_value *wv, *first_wv = 0, *prev_wv = 0;
   879 
   880   /* Number of elements seen so far, before boundary.  */
   881   int left_count = 0;
   882   /* true means we've seen the boundary between left-hand elts and
   883      right-hand.  */
   884   bool boundary_seen = false;
   885 
   886   *error = NULL;
   887 
   888   if (menu_items_n_panes > 1)
   889     {
   890       *error = "Multiple panes in dialog box";
   891       return Qnil;
   892     }
   893 
   894   /* Create a tree of widget_value objects
   895      representing the text label and buttons.  */
   896   {
   897     Lisp_Object pane_name;
   898     char *pane_string;
   899     pane_name = AREF (menu_items, MENU_ITEMS_PANE_NAME);
   900     pane_string = (NILP (pane_name)
   901                    ? "" : SSDATA (pane_name));
   902     prev_wv = make_widget_value ("message", pane_string, true, Qnil);
   903     first_wv = prev_wv;
   904 
   905     /* Loop over all panes and items, filling in the tree.  */
   906     i = MENU_ITEMS_PANE_LENGTH;
   907     while (i < menu_items_used)
   908       {
   909 
   910         /* Create a new item within current pane.  */
   911         Lisp_Object item_name, enable, descrip, help;
   912 
   913         item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
   914         enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
   915         descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
   916         help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
   917 
   918         if (NILP (item_name))
   919           {
   920             free_menubar_widget_value_tree (first_wv);
   921             *error = "Submenu in dialog items";
   922             return Qnil;
   923           }
   924         if (EQ (item_name, Qquote))
   925           {
   926             /* This is the boundary between left-side elts
   927                and right-side elts.  Stop incrementing right_count.  */
   928             boundary_seen = true;
   929             i++;
   930             continue;
   931           }
   932         if (nb_buttons >= 9)
   933           {
   934             free_menubar_widget_value_tree (first_wv);
   935             *error = "Too many dialog items";
   936             return Qnil;
   937           }
   938 
   939         wv = make_widget_value (button_names[nb_buttons],
   940                                 SSDATA (item_name),
   941                                 !NILP (enable), Qnil);
   942         prev_wv->next = wv;
   943         if (!NILP (descrip))
   944           wv->key = SSDATA (descrip);
   945         wv->call_data = aref_addr (menu_items, i);
   946         prev_wv = wv;
   947 
   948         if (! boundary_seen)
   949           left_count++;
   950 
   951         nb_buttons++;
   952         i += MENU_ITEMS_ITEM_LENGTH;
   953       }
   954 
   955     /* If the boundary was not specified,
   956        by default put half on the left and half on the right.  */
   957     if (! boundary_seen)
   958       left_count = nb_buttons - nb_buttons / 2;
   959 
   960     wv = make_widget_value (dialog_name, NULL, false, Qnil);
   961 
   962     /*  Frame title: 'Q' = Question, 'I' = Information.
   963         Can also have 'E' = Error if, one day, we want
   964         a popup for errors. */
   965     if (NILP (header))
   966       dialog_name[0] = 'Q';
   967     else
   968       dialog_name[0] = 'I';
   969 
   970     /* Dialog boxes use a really stupid name encoding
   971        which specifies how many buttons to use
   972        and how many buttons are on the right. */
   973     dialog_name[1] = '0' + nb_buttons;
   974     dialog_name[2] = 'B';
   975     dialog_name[3] = 'R';
   976     /* Number of buttons to put on the right.  */
   977     dialog_name[4] = '0' + nb_buttons - left_count;
   978     dialog_name[5] = 0;
   979     wv->contents = first_wv;
   980     first_wv = wv;
   981   }
   982 
   983   /* Actually create the dialog.  */
   984   dialog_id = widget_id_tick++;
   985   menu = lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv,
   986                            f->output_data.w32->widget, true, 0,
   987                            dialog_selection_callback, 0);
   988   lw_modify_all_widgets (dialog_id, first_wv->contents, TRUE);
   989 
   990   /* Free the widget_value objects we used to specify the contents.  */
   991   free_menubar_widget_value_tree (first_wv);
   992 
   993   /* No selection has been chosen yet.  */
   994   menu_item_selection = 0;
   995 
   996   /* Display the menu.  */
   997   lw_pop_up_all_widgets (dialog_id);
   998 
   999   /* Process events that apply to the menu.  */
  1000   popup_get_selection ((XEvent *) 0, FRAME_DISPLAY_INFO (f), dialog_id);
  1001 
  1002   lw_destroy_all_widgets (dialog_id);
  1003 
  1004   /* Find the selected item, and its pane, to return
  1005      the proper value.  */
  1006   if (menu_item_selection != 0)
  1007     {
  1008       i = 0;
  1009       while (i < menu_items_used)
  1010         {
  1011           Lisp_Object entry;
  1012 
  1013           if (EQ (AREF (menu_items, i), Qt))
  1014             i += MENU_ITEMS_PANE_LENGTH;
  1015           else
  1016             {
  1017               entry = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
  1018               if (menu_item_selection == i)
  1019                 return entry;
  1020               i += MENU_ITEMS_ITEM_LENGTH;
  1021             }
  1022         }
  1023     }
  1024   else
  1025     /* Make "Cancel" equivalent to C-g.  */
  1026     quit ();
  1027 
  1028   return Qnil;
  1029 }
  1030 #else /* !HAVE_DIALOGS  */
  1031 
  1032 /* Currently we only handle Yes No dialogs (y-or-n-p and yes-or-no-p) as
  1033    simple dialogs.  We could handle a few more, but I'm not aware of
  1034    anywhere in Emacs that uses the other specific dialog choices that
  1035    MessageBox provides.  */
  1036 
  1037 static bool
  1038 is_simple_dialog (Lisp_Object contents)
  1039 {
  1040   Lisp_Object options;
  1041   Lisp_Object name, yes, no, other;
  1042 
  1043   if (!CONSP (contents))
  1044     return false;
  1045   options = XCDR (contents);
  1046 
  1047   yes = build_string ("Yes");
  1048   no = build_string ("No");
  1049 
  1050   if (!CONSP (options))
  1051     return false;
  1052 
  1053   name = XCAR (options);
  1054   if (!CONSP (name))
  1055     return false;
  1056   name = XCAR (name);
  1057 
  1058   if (!NILP (Fstring_equal (name, yes)))
  1059     other = no;
  1060   else if (!NILP (Fstring_equal (name, no)))
  1061     other = yes;
  1062   else
  1063     return false;
  1064 
  1065   options = XCDR (options);
  1066   if (!CONSP (options))
  1067     return false;
  1068 
  1069   name = XCAR (options);
  1070   if (!CONSP (name))
  1071     return false;
  1072   name = XCAR (name);
  1073   if (NILP (Fstring_equal (name, other)))
  1074     return false;
  1075 
  1076   /* Check there are no more options.
  1077 
  1078      (FIXME: Since we use MB_YESNOCANCEL, we could also consider
  1079      dialogs with 3 options: Yes/No/Cancel as "simple".  */
  1080   options = XCDR (options);
  1081   return !(CONSP (options));
  1082 }
  1083 
  1084 static Lisp_Object
  1085 simple_dialog_show (struct frame *f, Lisp_Object contents, Lisp_Object header)
  1086 {
  1087   int answer;
  1088   UINT type;
  1089   Lisp_Object lispy_answer = Qnil, temp = XCAR (contents);
  1090 
  1091   /* We use MB_YESNOCANCEL to allow the user the equivalent of C-g
  1092      when the Yes/No question is asked vya y-or-n-p or
  1093      yes-or-no-p.  */
  1094   if (w32_yes_no_dialog_show_cancel)
  1095     type = MB_YESNOCANCEL;
  1096   else
  1097     type = MB_YESNO;
  1098 
  1099   /* Since we only handle Yes/No dialogs, and we already checked
  1100      is_simple_dialog, we don't need to worry about checking contents
  1101      to see what type of dialog to use.  */
  1102 
  1103   /* Use Unicode if possible, so any language can be displayed.  */
  1104   if (unicode_message_box)
  1105     {
  1106       WCHAR *text;
  1107       const WCHAR *title;
  1108       USE_SAFE_ALLOCA;
  1109 
  1110       if (STRINGP (temp))
  1111         {
  1112           char *utf8_text = SSDATA (ENCODE_UTF_8 (temp));
  1113           /* Be pessimistic about the number of characters needed.
  1114              Remember characters outside the BMP will take more than
  1115              one utf16 word, so we cannot simply use the character
  1116              length of temp.  */
  1117           int utf8_len = strlen (utf8_text);
  1118           text = SAFE_ALLOCA ((utf8_len + 1) * sizeof (WCHAR));
  1119           utf8to16 ((unsigned char *)utf8_text, utf8_len, text);
  1120         }
  1121       else
  1122         {
  1123           text = (WCHAR *)L"";
  1124         }
  1125 
  1126       if (NILP (header))
  1127         {
  1128           title = L"Question";
  1129           type |= MB_ICONQUESTION;
  1130         }
  1131       else
  1132         {
  1133           title = L"Information";
  1134           type |= MB_ICONINFORMATION;
  1135         }
  1136 
  1137       answer = unicode_message_box (FRAME_W32_WINDOW (f), text, title, type);
  1138       SAFE_FREE ();
  1139     }
  1140   else
  1141     {
  1142       const char *text, *title;
  1143 
  1144       /* Fall back on ANSI message box, but at least use system
  1145          encoding so questions representable by the system codepage
  1146          are encoded properly.  */
  1147       if (STRINGP (temp))
  1148         text = SSDATA (ENCODE_SYSTEM (temp));
  1149       else
  1150         text = "";
  1151 
  1152       if (NILP (header))
  1153         {
  1154           title = "Question";
  1155           type |= MB_ICONQUESTION;
  1156         }
  1157       else
  1158         {
  1159           title = "Information";
  1160           type |= MB_ICONINFORMATION;
  1161         }
  1162 
  1163       answer = MessageBox (FRAME_W32_WINDOW (f), text, title, type);
  1164     }
  1165 
  1166   if (answer == IDYES)
  1167     lispy_answer = build_string ("Yes");
  1168   else if (answer == IDNO)
  1169     lispy_answer = build_string ("No");
  1170   else
  1171     quit ();
  1172 
  1173   for (temp = XCDR (contents); CONSP (temp); temp = XCDR (temp))
  1174     {
  1175       Lisp_Object item, name, value;
  1176       item = XCAR (temp);
  1177       if (CONSP (item))
  1178         {
  1179           name = XCAR (item);
  1180           value = XCDR (item);
  1181         }
  1182       else
  1183         {
  1184           name = item;
  1185           value = Qnil;
  1186         }
  1187 
  1188       if (!NILP (Fstring_equal (name, lispy_answer)))
  1189         {
  1190           return value;
  1191         }
  1192     }
  1193   return quit ();
  1194 }
  1195 #endif  /* !HAVE_DIALOGS  */
  1196 
  1197 
  1198 /* UTF8: 0xxxxxxx, 110xxxxx 10xxxxxx, 1110xxxx, 10xxxxxx, 10xxxxxx */
  1199 static void
  1200 utf8to16 (unsigned char * src, int len, WCHAR * dest)
  1201 {
  1202   while (len > 0)
  1203     {
  1204       if (*src < 0x80)
  1205         {
  1206           *dest = (WCHAR) *src;
  1207           dest++; src++; len--;
  1208         }
  1209       /* Since we might get >3 byte sequences which we don't handle, ignore the extra parts.  */
  1210       else if (*src < 0xC0)
  1211         {
  1212           src++; len--;
  1213         }
  1214       /* 2 char UTF-8 sequence.  */
  1215       else if (*src <  0xE0)
  1216         {
  1217           *dest = (WCHAR) (((*src & 0x1f) << 6)
  1218                            | (*(src + 1) & 0x3f));
  1219           src += 2; len -= 2; dest++;
  1220         }
  1221       else if (*src < 0xF0)
  1222         {
  1223           *dest = (WCHAR) (((*src & 0x0f) << 12)
  1224                            | ((*(src + 1) & 0x3f) << 6)
  1225                            | (*(src + 2) & 0x3f));
  1226           src += 3; len -= 3; dest++;
  1227         }
  1228       else /* Not encodable. Insert Unicode Substitution char.  */
  1229         {
  1230           *dest = (WCHAR) 0xfffd;
  1231           src++; len--; dest++;
  1232         }
  1233     }
  1234   *dest = 0;
  1235 }
  1236 
  1237 static int
  1238 add_menu_item (HMENU menu, widget_value *wv, HMENU item)
  1239 {
  1240   UINT fuFlags;
  1241   char *out_string, *p, *q;
  1242   int return_value;
  1243   size_t nlen, orig_len;
  1244   USE_SAFE_ALLOCA;
  1245 
  1246   if (menu_separator_name_p (wv->name))
  1247     {
  1248       fuFlags = MF_SEPARATOR;
  1249       out_string = NULL;
  1250     }
  1251   else
  1252     {
  1253       if (wv->enabled)
  1254         fuFlags = MF_STRING;
  1255       else
  1256         fuFlags = MF_STRING | MF_GRAYED;
  1257 
  1258       if (wv->key != NULL)
  1259         {
  1260           out_string = SAFE_ALLOCA (strlen (wv->name) + strlen (wv->key) + 2);
  1261           p = stpcpy (out_string, wv->name);
  1262           p = stpcpy (p, "\t");
  1263           strcpy (p, wv->key);
  1264         }
  1265       else
  1266         out_string = (char *)wv->name;
  1267 
  1268       /* Quote any special characters within the menu item's text and
  1269          key binding.  */
  1270       nlen = orig_len = strlen (out_string);
  1271       if (unicode_append_menu)
  1272         {
  1273           /* With UTF-8, & cannot be part of a multibyte character.  */
  1274           for (p = out_string; *p; p++)
  1275             {
  1276               if (*p == '&')
  1277                 nlen++;
  1278             }
  1279         }
  1280 #ifndef NTGUI_UNICODE
  1281       else
  1282         {
  1283           /* If encoded with the system codepage, use multibyte string
  1284              functions in case of multibyte characters that contain '&'.  */
  1285           for (p = out_string; *p; p = _mbsinc (p))
  1286             {
  1287               if (_mbsnextc (p) == '&')
  1288                 nlen++;
  1289             }
  1290         }
  1291 #endif /* !NTGUI_UNICODE */
  1292 
  1293       if (nlen > orig_len)
  1294         {
  1295           p = out_string;
  1296           out_string = SAFE_ALLOCA (nlen + 1);
  1297           q = out_string;
  1298           while (*p)
  1299             {
  1300               if (unicode_append_menu)
  1301                 {
  1302                   if (*p == '&')
  1303                     *q++ = *p;
  1304                   *q++ = *p++;
  1305                 }
  1306 #ifndef NTGUI_UNICODE
  1307               else
  1308                 {
  1309                   if (_mbsnextc (p) == '&')
  1310                     {
  1311                       _mbsncpy (q, p, 1);
  1312                       q = _mbsinc (q);
  1313                     }
  1314                   _mbsncpy (q, p, 1);
  1315                   p = _mbsinc (p);
  1316                   q = _mbsinc (q);
  1317                 }
  1318 #endif /* !NTGUI_UNICODE */
  1319             }
  1320           *q = '\0';
  1321         }
  1322 
  1323       if (item != NULL)
  1324         fuFlags = MF_POPUP;
  1325       else if (wv->title || wv->call_data == 0)
  1326         {
  1327           /* Only use MF_OWNERDRAW if GetMenuItemInfo is usable, since
  1328              we can't deallocate the memory otherwise.  */
  1329           if (get_menu_item_info)
  1330             {
  1331               out_string = (char *) local_alloc (strlen (wv->name) + 1);
  1332               strcpy (out_string, wv->name);
  1333 #ifdef MENU_DEBUG
  1334               DebPrint ("Menu: allocating %ld for owner-draw", out_string);
  1335 #endif
  1336               fuFlags = MF_OWNERDRAW | MF_DISABLED;
  1337             }
  1338           else
  1339             fuFlags = MF_DISABLED;
  1340         }
  1341 
  1342       /* Draw radio buttons and tickboxes. */
  1343       else if (wv->selected && (wv->button_type == BUTTON_TYPE_TOGGLE ||
  1344                                 wv->button_type == BUTTON_TYPE_RADIO))
  1345         fuFlags |= MF_CHECKED;
  1346       else
  1347         fuFlags |= MF_UNCHECKED;
  1348     }
  1349 
  1350   if (unicode_append_menu && out_string)
  1351     {
  1352       /* Convert out_string from UTF-8 to UTF-16-LE.  */
  1353       int utf8_len = strlen (out_string);
  1354       WCHAR * utf16_string;
  1355       if (fuFlags & MF_OWNERDRAW)
  1356         utf16_string = local_alloc ((utf8_len + 1) * sizeof (WCHAR));
  1357       else
  1358         utf16_string = SAFE_ALLOCA ((utf8_len + 1) * sizeof (WCHAR));
  1359 
  1360       utf8to16 ((unsigned char *)out_string, utf8_len, utf16_string);
  1361       return_value = unicode_append_menu (menu, fuFlags,
  1362                                           item != NULL ? (UINT_PTR) item
  1363                                             : (UINT_PTR) wv->call_data,
  1364                                           utf16_string);
  1365 
  1366 #ifndef NTGUI_UNICODE /* Fallback does not apply when always UNICODE */
  1367       if (!return_value)
  1368         {
  1369           /* On W9x/ME, Unicode menus are not supported, though AppendMenuW
  1370              apparently does exist at least in some cases and appears to be
  1371              stubbed out to do nothing.  out_string is UTF-8, but since
  1372              our standard menus are in English and this is only going to
  1373              happen the first time a menu is used, the encoding is
  1374              of minor importance compared with menus not working at all.  */
  1375           return_value =
  1376             AppendMenu (menu, fuFlags,
  1377                         item != NULL ? (UINT_PTR) item: (UINT_PTR) wv->call_data,
  1378                         out_string);
  1379           /* Don't use Unicode menus in future, unless this is Windows
  1380              NT or later, where a failure of AppendMenuW does NOT mean
  1381              Unicode menus are unsupported.  */
  1382           if (osinfo_cache.dwPlatformId != VER_PLATFORM_WIN32_NT)
  1383             unicode_append_menu = NULL;
  1384         }
  1385 #endif /* NTGUI_UNICODE */
  1386 
  1387       if (unicode_append_menu && (fuFlags & MF_OWNERDRAW))
  1388         local_free (out_string);
  1389     }
  1390   else
  1391     {
  1392       return_value =
  1393         AppendMenu (menu,
  1394                     fuFlags,
  1395                     item != NULL ? (UINT_PTR) item : (UINT_PTR) wv->call_data,
  1396                     out_string );
  1397     }
  1398 
  1399   /* This must be done after the menu item is created.  */
  1400   if (!wv->title && wv->call_data != 0)
  1401     {
  1402       if (set_menu_item_info)
  1403         {
  1404           MENUITEMINFO info;
  1405           memset (&info, 0, sizeof (info));
  1406           info.cbSize = sizeof (info);
  1407           info.fMask = MIIM_DATA;
  1408 
  1409           /* Set help string for menu item.  Leave it as a pointer to
  1410              a Lisp_String until it is ready to be displayed, since GC
  1411              can happen while menus are active.  */
  1412           if (!NILP (wv->help))
  1413             {
  1414               /* We use XUNTAG below because in a 32-bit build
  1415                  --with-wide-int we cannot pass a Lisp_Object
  1416                  via a DWORD member of MENUITEMINFO.  */
  1417               /* As of Jul-2012, w32api headers say that dwItemData
  1418                  has DWORD type, but that's a bug: it should actually
  1419                  be ULONG_PTR, which is correct for 32-bit and 64-bit
  1420                  Windows alike.  MSVC headers get it right; hopefully,
  1421                  MinGW headers will, too.  */
  1422               eassert (STRINGP (wv->help));
  1423               info.dwItemData = (ULONG_PTR) XUNTAG (wv->help, Lisp_String,
  1424                                                     struct Lisp_String);
  1425             }
  1426           if (wv->button_type == BUTTON_TYPE_RADIO)
  1427             {
  1428               /* CheckMenuRadioItem allows us to differentiate TOGGLE and
  1429                  RADIO items, but is not available on NT 3.51 and earlier.  */
  1430               info.fMask |= MIIM_TYPE | MIIM_STATE;
  1431               info.fType = MFT_RADIOCHECK | MFT_STRING;
  1432               info.dwTypeData = out_string;
  1433               info.fState = wv->selected ? MFS_CHECKED : MFS_UNCHECKED;
  1434             }
  1435 
  1436           set_menu_item_info (menu,
  1437                               item != NULL ? (UINT_PTR) item : (UINT_PTR) wv->call_data,
  1438                               FALSE, &info);
  1439         }
  1440     }
  1441   SAFE_FREE ();
  1442   return return_value;
  1443 }
  1444 
  1445 /* Construct native Windows menu(bar) based on widget_value tree.  */
  1446 static int
  1447 fill_in_menu (HMENU menu, widget_value *wv)
  1448 {
  1449   for ( ; wv != NULL; wv = wv->next)
  1450     {
  1451       if (wv->contents)
  1452         {
  1453           HMENU sub_menu = CreatePopupMenu ();
  1454 
  1455           if (sub_menu == NULL)
  1456             return 0;
  1457 
  1458           if (!fill_in_menu (sub_menu, wv->contents) ||
  1459               !add_menu_item (menu, wv, sub_menu))
  1460             {
  1461               DestroyMenu (sub_menu);
  1462               return 0;
  1463             }
  1464         }
  1465       else
  1466         {
  1467           if (!add_menu_item (menu, wv, NULL))
  1468             return 0;
  1469         }
  1470     }
  1471   return 1;
  1472 }
  1473 
  1474 /* Display help string for currently pointed to menu item. Not
  1475    supported on NT 3.51 and earlier, as GetMenuItemInfo is not
  1476    available. */
  1477 void w32_menu_display_help (HWND, HMENU, UINT, UINT);
  1478 
  1479 void
  1480 w32_menu_display_help (HWND owner, HMENU menu, UINT item, UINT flags)
  1481 {
  1482   if (get_menu_item_info)
  1483     {
  1484       struct frame *f = w32_window_to_frame (&one_w32_display_info, owner);
  1485       Lisp_Object frame, help;
  1486 
  1487       /* No help echo on owner-draw menu items, or when the keyboard
  1488          is used to navigate the menus, since tooltips are distracting
  1489          if they pop up elsewhere.  */
  1490       if ((flags & MF_OWNERDRAW) || (flags & MF_POPUP)
  1491           || !(flags & MF_MOUSESELECT)
  1492           /* Ignore any dwItemData for menu items whose flags don't
  1493              have the MF_HILITE bit set.  These are dwItemData that
  1494              Windows sends our way, but they aren't pointers to our
  1495              Lisp_String objects, so trying to create Lisp_Strings out
  1496              of them below and pass that to the keyboard queue will
  1497              crash Emacs when we try to display those "strings".  It
  1498              is unclear why we get these dwItemData, or what they are:
  1499              sometimes they point to a wchar_t string that is the menu
  1500              title, sometimes to something that doesn't look like text
  1501              at all.  (The problematic data also comes with the 0x0800
  1502              bit set, but this bit is not documented, so we don't want
  1503              to depend on it.)  */
  1504           || !(flags & MF_HILITE))
  1505         help = Qnil;
  1506       else
  1507         {
  1508           MENUITEMINFO info;
  1509 
  1510           memset (&info, 0, sizeof (info));
  1511           info.cbSize = sizeof (info);
  1512           info.fMask = MIIM_DATA;
  1513           get_menu_item_info (menu, item, FALSE, &info);
  1514 
  1515           help =
  1516             info.dwItemData
  1517             ? make_lisp_ptr ((void *) info.dwItemData, Lisp_String)
  1518             : Qnil;
  1519         }
  1520 
  1521       /* Store the help echo in the keyboard buffer as the X toolkit
  1522          version does, rather than directly showing it. This seems to
  1523          solve the GC problems that were present when we based the
  1524          Windows code on the non-toolkit version.  */
  1525       if (f)
  1526         {
  1527           XSETFRAME (frame, f);
  1528           kbd_buffer_store_help_event (frame, help);
  1529         }
  1530       else
  1531         /* X version has a loop through frames here, which doesn't
  1532            appear to do anything, unless it has some side effect.  */
  1533         show_help_echo (help, Qnil, Qnil, Qnil);
  1534     }
  1535 }
  1536 
  1537 /* Free memory used by owner-drawn strings.  */
  1538 static void
  1539 w32_free_submenu_strings (HMENU menu)
  1540 {
  1541   int i, num = GetMenuItemCount (menu);
  1542   for (i = 0; i < num; i++)
  1543     {
  1544       MENUITEMINFO info;
  1545       memset (&info, 0, sizeof (info));
  1546       info.cbSize = sizeof (info);
  1547       info.fMask = MIIM_DATA | MIIM_TYPE | MIIM_SUBMENU;
  1548 
  1549       get_menu_item_info (menu, i, TRUE, &info);
  1550 
  1551       /* Owner-drawn names are held in dwItemData.  */
  1552       if ((info.fType & MF_OWNERDRAW) && info.dwItemData)
  1553         {
  1554 #ifdef MENU_DEBUG
  1555           DebPrint ("Menu: freeing %ld for owner-draw", info.dwItemData);
  1556 #endif
  1557           local_free (info.dwItemData);
  1558         }
  1559 
  1560       /* Recurse down submenus.  */
  1561       if (info.hSubMenu)
  1562         w32_free_submenu_strings (info.hSubMenu);
  1563     }
  1564 }
  1565 
  1566 void
  1567 w32_free_menu_strings (HWND hwnd)
  1568 {
  1569   HMENU menu = current_popup_menu;
  1570 
  1571   if (get_menu_item_info)
  1572     {
  1573       /* If there is no popup menu active, free the strings from the frame's
  1574          menubar.  */
  1575       if (!menu)
  1576         menu = GetMenu (hwnd);
  1577 
  1578       if (menu)
  1579         w32_free_submenu_strings (menu);
  1580     }
  1581 
  1582   current_popup_menu = NULL;
  1583 }
  1584 
  1585 /* The following is used by delayed window autoselection.  */
  1586 
  1587 DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p, 0, 0, 0,
  1588        doc: /* SKIP: real doc in xmenu.c.  */)
  1589   (void)
  1590 {
  1591   struct frame *f;
  1592   f = SELECTED_FRAME ();
  1593   return (f->output_data.w32->menubar_active > 0) ? Qt : Qnil;
  1594 }
  1595 
  1596 void
  1597 syms_of_w32menu (void)
  1598 {
  1599   globals_of_w32menu ();
  1600 
  1601   current_popup_menu = NULL;
  1602   PDUMPER_IGNORE (current_popup_menu);
  1603 
  1604   DEFSYM (Qdebug_on_next_call, "debug-on-next-call");
  1605   DEFSYM (Qunsupported__w32_dialog, "unsupported--w32-dialog");
  1606 
  1607   defsubr (&Smenu_or_popup_active_p);
  1608 }
  1609 
  1610 /*
  1611         globals_of_w32menu is used to initialize those global variables that
  1612         must always be initialized on startup even when the global variable
  1613         initialized is non zero (see the function main in emacs.c).
  1614         globals_of_w32menu is called from syms_of_w32menu when the global
  1615         variable initialized is 0 and directly from main when initialized
  1616         is non zero.
  1617  */
  1618 void
  1619 globals_of_w32menu (void)
  1620 {
  1621 #ifndef NTGUI_UNICODE
  1622   /* See if Get/SetMenuItemInfo functions are available.  */
  1623   HMODULE user32 = GetModuleHandle ("user32.dll");
  1624   get_menu_item_info = (GetMenuItemInfoA_Proc)
  1625     get_proc_addr (user32, "GetMenuItemInfoA");
  1626   set_menu_item_info = (SetMenuItemInfoA_Proc)
  1627     get_proc_addr (user32, "SetMenuItemInfoA");
  1628   unicode_append_menu = (AppendMenuW_Proc)
  1629     get_proc_addr (user32, "AppendMenuW");
  1630   unicode_message_box = (MessageBoxW_Proc)
  1631     get_proc_addr (user32, "MessageBoxW");
  1632 #endif /* !NTGUI_UNICODE */
  1633 }

/* [<][>][^][v][top][bottom][index][help] */