Changeset 1661

Show
Ignore:
Timestamp:
02/17/98 01:45:16 (11 years ago)
Author:
himi
Message:

FSF Emacs 20.7 imported

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/GNU/src/w32menu.c

    r1635 r1661  
    11/* Menu support for GNU Emacs on the Microsoft W32 API. 
    2    Copyright (C) 1986, 88, 93, 94, 96, 98, 1999 Free Software Foundation, Inc. 
     2   Copyright (C) 1986, 1988, 1993, 1994, 1996, 1998 Free Software Foundation, Inc. 
    33 
    44This file is part of GNU Emacs. 
     
    1919Boston, MA 02111-1307, USA.  */ 
    2020 
     21#include <signal.h> 
    2122#include <config.h> 
    22 #include <signal.h> 
    2323 
    2424#include <stdio.h> 
    2525#include "lisp.h" 
    2626#include "termhooks.h" 
    27 #include "keyboard.h" 
    2827#include "frame.h" 
    2928#include "window.h" 
     29#include "keyboard.h" 
    3030#include "blockinput.h" 
    3131#include "buffer.h" 
     
    4646 
    4747#undef HAVE_MULTILINGUAL_MENU 
    48 #undef HAVE_DIALOGS /* TODO: Implement native dialogs.  */ 
    4948 
    5049/******************************************************************/ 
     
    5453typedef char Boolean; 
    5554 
    56 enum button_type 
    57 
    58   BUTTON_TYPE_NONE, 
    59   BUTTON_TYPE_TOGGLE, 
    60   BUTTON_TYPE_RADIO 
    61 }; 
     55#define True 1 
     56#define False 0 
     57 
     58typedef enum _change_type 
     59
     60  NO_CHANGE = 0, 
     61  INVISIBLE_CHANGE = 1, 
     62  VISIBLE_CHANGE = 2, 
     63  STRUCTURAL_CHANGE = 3 
     64} change_type; 
    6265 
    6366typedef struct _widget_value 
     
    6972  /* keyboard equivalent. no implications for XtTranslations */  
    7073  char*         key; 
    71   /* Help string or null if none.  */ 
    72   char          *help; 
    7374  /* true if enabled */ 
    7475  Boolean       enabled; 
    7576  /* true if selected */ 
    7677  Boolean       selected; 
    77   /* The type of a button.  */ 
    78   enum button_type button_type; 
    7978  /* true if menu title */ 
    8079  Boolean       title; 
     
    140139void set_frame_menubar (); 
    141140 
    142 static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, 
    143                                 Lisp_Object, Lisp_Object, Lisp_Object, 
    144                                 Lisp_Object, Lisp_Object)); 
     141static Lisp_Object w32_menu_show (); 
    145142static Lisp_Object w32_dialog_show (); 
    146 static Lisp_Object w32_menu_show (); 
    147143 
    148144static void keymap_panes (); 
     
    178174#define MENU_ITEMS_PANE_LENGTH 3 
    179175 
    180 enum menu_item_idx 
    181 
    182   MENU_ITEMS_ITEM_NAME = 0, 
    183   MENU_ITEMS_ITEM_ENABLE, 
    184   MENU_ITEMS_ITEM_VALUE, 
    185   MENU_ITEMS_ITEM_EQUIV_KEY, 
    186   MENU_ITEMS_ITEM_DEFINITION, 
    187   MENU_ITEMS_ITEM_TYPE, 
    188   MENU_ITEMS_ITEM_SELECTED, 
    189   MENU_ITEMS_ITEM_HELP, 
    190   MENU_ITEMS_ITEM_LENGTH 
    191 }; 
     176#define MENU_ITEMS_ITEM_NAME 0 
     177#define MENU_ITEMS_ITEM_ENABLE 1 
     178#define MENU_ITEMS_ITEM_VALUE 2 
     179#define MENU_ITEMS_ITEM_EQUIV_KEY 3 
     180#define MENU_ITEMS_ITEM_DEFINITION 4 
     181#define MENU_ITEMS_ITEM_LENGTH 5 
    192182 
    193183static Lisp_Object menu_items; 
     
    210200static int popup_activated_flag; 
    211201 
    212 static int next_menubar_widget_id; 
    213  
    214202/* This is set nonzero after the user activates the menu bar, and set 
    215203   to zero again after the menu bars are redisplayed by prepare_menu_bar. 
     
    223211 
    224212/* Return the frame whose ->output_data.w32->menubar_widget equals 
    225    ID, or 0 if none.  */ 
     213   MENU, or 0 if none.  */ 
    226214 
    227215static struct frame * 
    228 menubar_id_to_frame (id) 
    229      HMENU id; 
     216menubar_id_to_frame (HMENU menu) 
    230217{ 
    231218  Lisp_Object tail, frame; 
    232219  FRAME_PTR f; 
    233220 
    234   for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail)
    235     { 
    236       frame = XCAR (tail)
     221  for (tail = Vframe_list; GC_CONSP (tail); tail = XCONS (tail)->cdr
     222    { 
     223      frame = XCONS (tail)->car
    237224      if (!GC_FRAMEP (frame)) 
    238225        continue; 
    239226      f = XFRAME (frame); 
    240       if (!FRAME_WINDOW_P (f)
     227      if (f->output_data.nothing == 1
    241228        continue; 
    242       if (f->output_data.w32->menubar_widget == id
     229      if (f->output_data.w32->menubar_widget == menu
    243230        return f; 
    244231    } 
     
    353340} 
    354341 
    355 /* Push one menu item into the current pane.  NAME is the string to 
    356    display.  ENABLE if non-nil means this item can be selected.  KEY 
    357    is the key generated by choosing this item, or nil if this item 
    358    doesn't really have a definition.  DEF is the definition of this 
    359    item.  EQUIV is the textual description of the keyboard equivalent 
    360    for this item (or nil if none).  TYPE is the type of this menu 
    361    item, one of nil, `toggle' or `radio'. */ 
     342/* Push one menu item into the current pane. 
     343   NAME is the string to display.  ENABLE if non-nil means 
     344   this item can be selected.  KEY is the key generated by 
     345   choosing this item, or nil if this item doesn't really have a definition. 
     346   DEF is the definition of this item. 
     347   EQUIV is the textual description of the keyboard equivalent for 
     348   this item (or nil if none). */ 
    362349 
    363350static void 
    364 push_menu_item (name, enable, key, def, equiv, type, selected, help
    365      Lisp_Object name, enable, key, def, equiv, type, selected, help
     351push_menu_item (name, enable, key, def, equiv
     352     Lisp_Object name, enable, key, def, equiv
    366353{ 
    367354  if (menu_items_used + MENU_ITEMS_ITEM_LENGTH > menu_items_allocated) 
     
    373360  XVECTOR (menu_items)->contents[menu_items_used++] = equiv; 
    374361  XVECTOR (menu_items)->contents[menu_items_used++] = def; 
    375   XVECTOR (menu_items)->contents[menu_items_used++] = type; 
    376   XVECTOR (menu_items)->contents[menu_items_used++] = selected; 
    377   XVECTOR (menu_items)->contents[menu_items_used++] = help; 
    378362} 
    379363  
     
    397381     P is the number of panes we have made so far.  */ 
    398382  for (mapno = 0; mapno < nmaps; mapno++) 
    399     single_keymap_panes (keymaps[mapno], 
    400                          map_prompt (keymaps[mapno]), Qnil, notreal, 10); 
     383    single_keymap_panes (keymaps[mapno], Qnil, Qnil, notreal, 10); 
    401384 
    402385  finish_menu_items (); 
     
    423406  Lisp_Object tail, item; 
    424407  struct gcpro gcpro1, gcpro2; 
     408  int notbuttons = 0; 
    425409 
    426410  if (maxdepth <= 0) 
     
    429413  push_menu_pane (pane_name, prefix); 
    430414 
    431   for (tail = keymap; CONSP (tail); tail = XCDR (tail)) 
     415#ifndef HAVE_BOXES 
     416  /* Remember index for first item in this pane so we can go back and 
     417     add a prefix when (if) we see the first button.  After that, notbuttons 
     418     is set to 0, to mark that we have seen a button and all non button 
     419     items need a prefix.  */ 
     420  notbuttons = menu_items_used; 
     421#endif 
     422 
     423  for (tail = keymap; CONSP (tail); tail = XCONS (tail)->cdr) 
    432424    { 
    433425      GCPRO2 (keymap, pending_maps); 
    434426      /* Look at each key binding, and if it is a menu item add it 
    435427         to this menu.  */ 
    436       item = XCAR (tail)
     428      item = XCONS (tail)->car
    437429      if (CONSP (item)) 
    438         single_menu_item (XCAR (item), XCDR (item)
    439                           &pending_maps, notreal, maxdepth); 
     430        single_menu_item (XCONS (item)->car, XCONS (item)->cdr
     431                          &pending_maps, notreal, maxdepth, &notbuttons); 
    440432      else if (VECTORP (item)) 
    441433        { 
     
    448440              XSETFASTINT (character, c); 
    449441              single_menu_item (character, XVECTOR (item)->contents[c], 
    450                                 &pending_maps, notreal, maxdepth); 
     442                                &pending_maps, notreal, maxdepth, &notbuttons); 
    451443            } 
    452444        } 
     
    459451      Lisp_Object elt, eltcdr, string; 
    460452      elt = Fcar (pending_maps); 
    461       eltcdr = XCDR (elt)
    462       string = XCAR (eltcdr)
     453      eltcdr = XCONS (elt)->cdr
     454      string = XCONS (eltcdr)->car
    463455      /* We no longer discard the @ from the beginning of the string here. 
    464456         Instead, we do this in w32_menu_show.  */ 
    465457      single_keymap_panes (Fcar (elt), string, 
    466                            XCDR (eltcdr), notreal, maxdepth - 1); 
     458                           XCONS (eltcdr)->cdr, notreal, maxdepth - 1); 
    467459      pending_maps = Fcdr (pending_maps); 
    468460    } 
     
    476468   If NOTREAL is nonzero, only check for equivalent key bindings, don't 
    477469   evaluate expressions in menu items and don't make any menu. 
    478    If we encounter submenus deeper than MAXDEPTH levels, ignore them.  */ 
     470   If we encounter submenus deeper than MAXDEPTH levels, ignore them. 
     471   NOTBUTTONS_PTR is only used when simulating toggle boxes and radio 
     472   buttons.  It points to variable notbuttons in single_keymap_panes, 
     473   which keeps track of if we have seen a button in this menu or not.  */ 
    479474 
    480475static void 
    481 single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth) 
     476single_menu_item (key, item, pending_maps_ptr, notreal, maxdepth, 
     477                  notbuttons_ptr) 
    482478     Lisp_Object key, item; 
    483479     Lisp_Object *pending_maps_ptr; 
    484480     int maxdepth, notreal; 
    485 
    486   Lisp_Object map, item_string, enabled; 
     481     int *notbuttons_ptr; 
     482
     483  Lisp_Object def, map, item_string, enabled; 
    487484  struct gcpro gcpro1, gcpro2; 
    488485  int res; 
     
    518515    } 
    519516 
     517#ifndef HAVE_BOXES 
     518  /* Simulate radio buttons and toggle boxes by putting a prefix in 
     519     front of them.  */ 
     520  { 
     521    Lisp_Object prefix = Qnil; 
     522    Lisp_Object type = XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE]; 
     523    if (!NILP (type)) 
     524      { 
     525        Lisp_Object selected 
     526          = XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED]; 
     527 
     528        if (*notbuttons_ptr) 
     529          /* The first button. Line up previous items in this menu.  */ 
     530          { 
     531            int index = *notbuttons_ptr; /* Index for first item this menu.  */ 
     532            int submenu = 0; 
     533            Lisp_Object tem; 
     534            while (index < menu_items_used) 
     535              { 
     536                tem 
     537                  = XVECTOR (menu_items)->contents[index + MENU_ITEMS_ITEM_NAME]; 
     538                if (NILP (tem)) 
     539                  { 
     540                    index++; 
     541                    submenu++;          /* Skip sub menu.  */ 
     542                  } 
     543                else if (EQ (tem, Qlambda)) 
     544                  { 
     545                    index++; 
     546                    submenu--;          /* End sub menu.  */ 
     547                  } 
     548                else if (EQ (tem, Qt)) 
     549                  index += 3;           /* Skip new pane marker. */ 
     550                else if (EQ (tem, Qquote)) 
     551                  index++;              /* Skip a left, right divider. */ 
     552                else 
     553                  { 
     554                    if (!submenu && XSTRING (tem)->data[0] != '\0' 
     555                        && XSTRING (tem)->data[0] != '-') 
     556                      XVECTOR (menu_items)->contents[index + MENU_ITEMS_ITEM_NAME] 
     557                        = concat2 (build_string ("    "), tem); 
     558                    index += MENU_ITEMS_ITEM_LENGTH; 
     559                  } 
     560              } 
     561            *notbuttons_ptr = 0; 
     562          } 
     563 
     564        /* Calculate prefix, if any, for this item.  */ 
     565        if (EQ (type, QCtoggle)) 
     566          prefix = build_string (NILP (selected) ? "[ ] " : "[X] "); 
     567        else if (EQ (type, QCradio)) 
     568          prefix = build_string (NILP (selected) ? "( ) " : "(*) "); 
     569      } 
     570    /* Not a button. If we have earlier buttons, then we need a prefix.  */ 
     571    else if (!*notbuttons_ptr && XSTRING (item_string)->data[0] != '\0' 
     572             && XSTRING (item_string)->data[0] != '-') 
     573      prefix = build_string ("    "); 
     574 
     575    if (!NILP (prefix)) 
     576      item_string = concat2 (prefix, item_string); 
     577  } 
     578#endif /* not HAVE_BOXES */ 
     579  
     580#if 0 
     581  if (!NILP(map)) 
     582    /* Indicate visually that this is a submenu.  */ 
     583    item_string = concat2 (item_string, build_string (" >")); 
     584#endif 
     585 
    520586  push_menu_item (item_string, enabled, key, 
    521587                  XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF], 
    522                   XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ], 
    523                   XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE], 
    524                   XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED], 
    525                   XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]); 
    526  
     588                  XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ]); 
     589 
     590#if 1 
    527591  /* Display a submenu using the toolkit.  */ 
    528592  if (! (NILP (map) || NILP (enabled))) 
     
    532596      push_submenu_end (); 
    533597    } 
     598#endif 
    534599} 
    535600  
     
    573638      item = Fcar (tail); 
    574639      if (STRINGP (item)) 
    575         push_menu_item (item, Qnil, Qnil, Qt, Qnil, Qnil, Qnil, Qnil); 
     640        push_menu_item (item, Qnil, Qnil, Qt, Qnil); 
    576641      else if (NILP (item)) 
    577642        push_left_right_boundary (); 
     
    581646          item1 = Fcar (item); 
    582647          CHECK_STRING (item1, 1); 
    583           push_menu_item (item1, Qt, Fcdr (item), Qt, Qnil, Qnil, Qnil, Qnil); 
     648          push_menu_item (item1, Qt, Fcdr (item), Qt, Qnil); 
    584649        } 
    585650    } 
     
    622687     Lisp_Object position, menu; 
    623688{ 
     689  int number_of_panes, panes; 
    624690  Lisp_Object keymap, tem; 
    625691  int xpos, ypos; 
     
    627693  char *error_name; 
    628694  Lisp_Object selection; 
     695  int i, j; 
    629696  FRAME_PTR f; 
    630697  Lisp_Object x, y, window; 
     
    640707      /* Decode the first argument: find the window and the coordinates.  */ 
    641708      if (EQ (position, Qt) 
    642           || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) 
    643                                    || EQ (XCAR (position), Qtool_bar)))) 
     709          || (CONSP (position) && EQ (XCONS (position)->car, Qmenu_bar))) 
    644710        { 
    645711          /* Use the mouse's current position.  */ 
    646           FRAME_PTR new_f = SELECTED_FRAME ()
     712          FRAME_PTR new_f = selected_frame
    647713          Lisp_Object bar_window; 
    648           enum scroll_bar_part part; 
     714          int part; 
    649715          unsigned long time; 
    650716 
     
    697763          f = XFRAME (WINDOW_FRAME (XWINDOW (window))); 
    698764 
    699           xpos = (FONT_WIDTH (FRAME_FONT (f)
     765          xpos = (FONT_WIDTH (f->output_data.w32->font
    700766                  * XFASTINT (XWINDOW (window)->left)); 
    701           ypos = (FRAME_LINE_HEIGHT (f) 
     767          ypos = (f->output_data.w32->line_height 
    702768                  * XFASTINT (XWINDOW (window)->top)); 
    703769        } 
     
    720786  /* Decode the menu items from what was specified.  */ 
    721787 
    722   keymap = get_keymap (menu, 0, 0); 
    723   if (CONSP (keymap)) 
     788  keymap = Fkeymapp (menu); 
     789  tem = Qnil; 
     790  if (CONSP (menu)) 
     791    tem = Fkeymapp (Fcar (menu)); 
     792  if (!NILP (keymap)) 
    724793    { 
    725794      /* We were given a keymap.  Extract menu info from the keymap.  */ 
    726795      Lisp_Object prompt; 
     796      keymap = get_keymap (menu); 
    727797 
    728798      /* Extract the detailed info to make one pane.  */ 
     
    741811      keymaps = 1; 
    742812    } 
    743   else if (CONSP (menu) && KEYMAPP (XCAR (menu))) 
     813  else if (!NILP (tem)) 
    744814    { 
    745815      /* We were given a list of keymaps.  */ 
     
    757827          Lisp_Object prompt; 
    758828 
    759           maps[i++] = keymap = get_keymap (Fcar (tem), 1, 0); 
     829          maps[i++] = keymap = get_keymap (Fcar (tem)); 
    760830 
    761831          prompt = map_prompt (keymap); 
     
    835905  /* Decode the first argument: find the window or frame to use.  */ 
    836906  if (EQ (position, Qt) 
    837       || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar) 
    838                                || EQ (XCAR (position), Qtool_bar)))) 
     907      || (CONSP (position) && EQ (XCONS (position)->car, Qmenu_bar))) 
    839908    { 
    840909#if 0 /* Using the frame the mouse is on may not be right.  */ 
    841910      /* Use the mouse's current position.  */ 
    842       FRAME_PTR new_f = SELECTED_FRAME ()
     911      FRAME_PTR new_f = selected_frame
    843912      Lisp_Object bar_window; 
    844       enum scroll_bar_part part; 
     913      int part; 
    845914      unsigned long time; 
    846915      Lisp_Object x, y; 
     
    886955    CHECK_WINDOW (window, 0); 
    887956 
    888 #ifndef HAVE_DIALOGS 
     957#if 1 
    889958  /* Display a menu with these alternatives 
    890959     in the middle of frame F.  */ 
     
    899968                          Fcons (Fcar (contents), Fcons (contents, Qnil))); 
    900969  } 
    901 #else /* HAVE_DIALOGS */ 
     970#else 
    902971  { 
    903972    Lisp_Object title; 
     
    921990    return selection; 
    922991  } 
    923 #endif /* HAVE_DIALOGS */ 
     992#endif 
    924993} 
    925994 
     
    9361005   This way we can safely execute Lisp code.  */ 
    9371006    
    938 void 
    9391007x_activate_menubar (f) 
    9401008     FRAME_PTR f; 
     
    9651033  if (!f) 
    9661034    return; 
    967   entry = Qnil; 
    9681035  subprefix_stack = (Lisp_Object *) alloca (f->menu_bar_items_used * sizeof (Lisp_Object)); 
    9691036  vector = f->menu_bar_vector; 
     
    10001067 
    10011068              XSETFRAME (frame, f); 
    1002               buf.kind = MENU_BAR_EVENT; 
    1003               buf.frame_or_window = frame; 
    1004               buf.arg = frame; 
     1069              buf.kind = menu_bar_event; 
     1070              buf.frame_or_window = Fcons (frame, Fcons (Qmenu_bar, Qnil)); 
    10051071              kbd_buffer_store_event (&buf); 
    10061072 
     
    10081074                if (!NILP (subprefix_stack[j])) 
    10091075                  { 
    1010                     buf.kind = MENU_BAR_EVENT; 
    1011                     buf.frame_or_window = frame; 
    1012                     buf.arg = subprefix_stack[j]; 
     1076                    buf.kind = menu_bar_event; 
     1077                    buf.frame_or_window = Fcons (frame, subprefix_stack[j]); 
    10131078                    kbd_buffer_store_event (&buf); 
    10141079                  } 
     
    10161081              if (!NILP (prefix)) 
    10171082                { 
    1018                   buf.kind = MENU_BAR_EVENT; 
    1019                   buf.frame_or_window = frame; 
    1020                   buf.arg = prefix; 
     1083                  buf.kind = menu_bar_event; 
     1084                  buf.frame_or_window = Fcons (frame, prefix); 
    10211085                  kbd_buffer_store_event (&buf); 
    10221086                } 
    10231087 
    1024               buf.kind = MENU_BAR_EVENT; 
    1025               buf.frame_or_window = frame; 
    1026               buf.arg = entry; 
     1088              buf.kind = menu_bar_event; 
     1089              buf.frame_or_window = Fcons (frame, entry); 
    10271090              kbd_buffer_store_event (&buf); 
    10281091 
     
    10911154  Lisp_Object *mapvec; 
    10921155  widget_value **submenu_stack; 
     1156  int mapno; 
    10931157  int previous_items = menu_items_used; 
    10941158  int top_level_items = 0; 
     
    11121176    { 
    11131177      if (SYMBOLP (mapvec[i]) 
    1114           || (CONSP (mapvec[i]) && !KEYMAPP (mapvec[i]))) 
     1178          || (CONSP (mapvec[i]) 
     1179              && NILP (Fkeymapp (mapvec[i])))) 
    11151180        { 
    11161181          /* Here we have a command at top level in the menu bar 
     
    11181183          top_level_items = 1; 
    11191184          push_menu_pane (Qnil, Qnil); 
    1120           push_menu_item (item_name, Qt, item_key, mapvec[i], 
    1121                           Qnil, Qnil, Qnil, Qnil); 
     1185          push_menu_item (item_name, Qt, item_key, mapvec[i], Qnil); 
    11221186        } 
    11231187      else 
     
    11341198  wv->value = 0; 
    11351199  wv->enabled = 1; 
    1136   wv->button_type = BUTTON_TYPE_NONE; 
    11371200  first_wv = wv; 
    11381201  save_wv = 0; 
     
    12011264              wv->value = 0; 
    12021265              wv->enabled = 1; 
    1203               wv->button_type = BUTTON_TYPE_NONE; 
    12041266            } 
    12051267          save_wv = wv; 
     
    12101272        { 
    12111273          /* Create a new item within current pane.  */ 
    1212           Lisp_Object item_name, enable, descrip, def, type, selected; 
    1213           Lisp_Object help; 
    1214  
     1274          Lisp_Object item_name, enable, descrip, def; 
    12151275          item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME]; 
    12161276          enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE]; 
     
    12181278            = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY]; 
    12191279          def = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_DEFINITION]; 
    1220           type = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_TYPE]; 
    1221           selected = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_SELECTED]; 
    1222           help = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_HELP]; 
    1223  
    12241280#ifndef HAVE_MULTILINGUAL_MENU 
    12251281          if (STRING_MULTIBYTE (item_name)) 
     
    12281284            descrip = ENCODE_SYSTEM (descrip); 
    12291285#endif 
    1230  
    12311286          wv = xmalloc_widget_value (); 
    12321287          if (prev_wv)  
     
    12431298          wv->call_data = (!NILP (def) ? (void *) (EMACS_INT) i : 0); 
    12441299          wv->enabled = !NILP (enable); 
    1245  
    1246           if (NILP (type)) 
    1247             wv->button_type = BUTTON_TYPE_NONE; 
    1248           else if (EQ (type, QCradio)) 
    1249             wv->button_type = BUTTON_TYPE_RADIO; 
    1250           else if (EQ (type, QCtoggle)) 
    1251             wv->button_type = BUTTON_TYPE_TOGGLE; 
    1252           else 
    1253             abort (); 
    1254  
    1255           wv->selected = !NILP (selected); 
    1256           if (STRINGP (help)) 
    1257             wv->help = (char *) XSTRING (help)->data; 
    1258           else 
    1259             wv->help = NULL; 
    1260  
    12611300          prev_wv = wv; 
    12621301 
     
    12881327{ 
    12891328  HMENU menubar_widget = f->output_data.w32->menubar_widget; 
    1290   Lisp_Object items
     1329  Lisp_Object tail, items, frame
    12911330  widget_value *wv, *first_wv, *prev_wv = 0; 
    12921331  int i; 
     
    13071346  wv->value = 0; 
    13081347  wv->enabled = 1; 
    1309   wv->button_type = BUTTON_TYPE_NONE; 
    13101348  first_wv = wv; 
    13111349 
     
    13431381 
    13441382      /* Run the Lucid hook.  */ 
    1345       safe_run_hooks (Qactivate_menubar_hook); 
     1383      call1 (Vrun_hooks, Qactivate_menubar_hook); 
    13461384      /* If it has changed current-menubar from previous value, 
    13471385         really recompute the menubar from the value.  */ 
     
    13801418          /* Don't set wv->name here; GC during the loop might relocate it.  */ 
    13811419          wv->enabled = 1; 
    1382           wv->button_type = BUTTON_TYPE_NONE; 
    13831420          prev_wv = wv; 
    13841421        } 
     
    14241461    { 
    14251462      /* Make a widget-value tree containing 
    1426          just the top level menu bar strings.  */ 
     1463         just the top level menu bar strings. 
     1464 
     1465         It turns out to be worth comparing the new contents with the 
     1466         previous contents to avoid unnecessary rebuilding even of just 
     1467         the top-level menu bar, which turns out to be fairly slow.  We 
     1468         co-opt f->menu_bar_vector for this purpose, since its contents 
     1469         are effectively discarded at this point anyway. 
     1470 
     1471         Note that the lisp-level hooks have already been run by 
     1472         update_menu_bar - it's kinda a shame the code is duplicated 
     1473         above as well for deep_p, but there we are.  */ 
    14271474 
    14281475      items = FRAME_MENU_BAR_ITEMS (f); 
     1476 
     1477      /* If there has been no change in the Lisp-level contents of just 
     1478         the menu bar itself, skip redisplaying it.  Just exit.  */ 
     1479      for (i = 0; i < f->menu_bar_items_used; i += 4) 
     1480        if (i == XVECTOR (items)->size 
     1481            || (XVECTOR (f->menu_bar_vector)->contents[i] 
     1482                != XVECTOR (items)->contents[i])) 
     1483          break; 
     1484      if (i == XVECTOR (items)->size && i == f->menu_bar_items_used && i != 0) 
     1485          return; 
     1486 
    14291487      for (i = 0; i < XVECTOR (items)->size; i += 4) 
    14301488        { 
     
    14391497          wv->value = 0; 
    14401498          wv->enabled = 1; 
    1441           wv->button_type = BUTTON_TYPE_NONE; 
    14421499          /* This prevents lwlib from assuming this 
    14431500             menu item is really supposed to be empty.  */ 
     
    14531510        } 
    14541511 
    1455       /* Forget what we thought we knew about what is in the 
    1456          detailed contents of the menu bar menus. 
    1457          Changing the top level always destroys the contents.  */ 
    1458       f->menu_bar_items_used = 0; 
     1512      /* Remember the contents of FRAME_MENU_BAR_ITEMS (f) in 
     1513         f->menu_bar_vector, so we can check whether the top-level 
     1514         menubar contents have changed next time.  */ 
     1515      if (XVECTOR (f->menu_bar_vector)->size < XVECTOR (items)->size) 
     1516        f->menu_bar_vector 
     1517          = Fmake_vector (make_number (XVECTOR (items)->size), Qnil); 
     1518      bcopy (XVECTOR (items)->contents, 
     1519             XVECTOR (f->menu_bar_vector)->contents, 
     1520             XVECTOR (items)->size * sizeof (Lisp_Object)); 
     1521      f->menu_bar_items_used = XVECTOR (items)->size; 
    14591522    } 
    14601523 
     
    15641627    = (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object)); 
    15651628  int submenu_depth = 0; 
     1629 
    15661630  int first_pane; 
     1631  int next_release_must_exit = 0; 
    15671632 
    15681633  *error = NULL; 
     
    15801645  wv->value = 0; 
    15811646  wv->enabled = 1; 
    1582   wv->button_type = BUTTON_TYPE_NONE; 
    15831647  first_wv = wv; 
    15841648  first_pane = 1; 
     
    16431707              wv->value = 0; 
    16441708              wv->enabled = 1; 
    1645               wv->button_type = BUTTON_TYPE_NONE; 
    16461709              save_wv = wv; 
    16471710              prev_wv = 0; 
     
    16581721        { 
    16591722          /* Create a new item within current pane.  */ 
    1660           Lisp_Object item_name, enable, descrip, def, type, selected, help; 
    1661  
     1723          Lisp_Object item_name, enable, descrip, def; 
    16621724          item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME]; 
    16631725          enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE]; 
     
    16651727            = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY]; 
    16661728          def = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_DEFINITION]; 
    1667           type = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_TYPE]; 
    1668           selected = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_SELECTED]; 
    1669           help = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_HELP]; 
    16701729 
    16711730#ifndef HAVE_MULTILINGUAL_MENU 
    1672           if (STRINGP (item_name) && STRING_MULTIBYTE (item_name)) 
    1673             item_name = ENCODE_SYSTEM (item_name); 
    1674           if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) 
    1675             descrip = ENCODE_SYSTEM (descrip); 
     1731         if (STRING_MULTIBYTE (item_name)) 
     1732           item_name = ENCODE_SYSTEM (item_name); 
     1733         if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) 
     1734           descrip = ENCODE_SYSTEM (descrip); 
    16761735#endif 
    16771736 
     
    16891748          wv->call_data = !NILP (def) ? (void *) (EMACS_INT) i : 0; 
    16901749          wv->enabled = !NILP (enable); 
    1691  
    1692           if (NILP (type)) 
    1693             wv->button_type = BUTTON_TYPE_NONE; 
    1694           else if (EQ (type, QCtoggle)) 
    1695             wv->button_type = BUTTON_TYPE_TOGGLE; 
    1696           else if (EQ (type, QCradio)) 
    1697             wv->button_type = BUTTON_TYPE_RADIO; 
    1698           else 
    1699             abort (); 
    1700  
    1701           wv->selected = !NILP (selected); 
    1702  
    1703           if (STRINGP (help)) 
    1704             wv->help = (char *) XSTRING (help)->data; 
    1705           else 
    1706             wv->help = NULL; 
    1707  
    17081750          prev_wv = wv; 
    17091751 
     
    17281770#endif 
    17291771      wv_title->name = (char *) XSTRING (title)->data; 
    1730       wv_title->enabled = TRUE; 
    1731       wv_title->title = TRUE; 
    1732       wv_title->button_type = BUTTON_TYPE_NONE; 
     1772      /* Handle title specially, so it looks better.  */ 
     1773      wv_title->title = True; 
    17331774      wv_title->next = wv_sep; 
    17341775      first_wv->contents = wv_title; 
     
    17381779  menu = CreatePopupMenu (); 
    17391780  fill_in_menu (menu, first_wv->contents); 
    1740  
     1781     
    17411782  /* Adjust coordinates to be root-window-relative.  */ 
    17421783  pos.x = x; 
     
    17441785  ClientToScreen (FRAME_W32_WINDOW (f), &pos); 
    17451786 
     1787  /* Free the widget_value objects we used to specify the contents.  */ 
     1788  free_menubar_widget_value_tree (first_wv); 
     1789 
    17461790  /* No selection has been chosen yet.  */ 
    17471791  menu_item_selection = 0; 
     
    17561800  discard_mouse_events (); 
    17571801 
    1758   /* Free the widget_value objects we used to specify the contents.  */ 
    1759   free_menubar_widget_value_tree (first_wv); 
    1760  
    17611802  DestroyMenu (menu); 
    17621803 
     
    17671808      Lisp_Object prefix, entry; 
    17681809 
    1769       prefix = entry = Qnil; 
     1810      prefix = Qnil; 
    17701811      i = 0; 
    17711812      while (i < menu_items_used) 
     
    18351876  int menu_item_selection; 
    18361877 
    1837   widget_value *wv, *first_wv = 0, *prev_wv = 0; 
     1878  widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0; 
    18381879 
    18391880  /* Number of elements seen so far, before boundary.  */ 
     
    18731914         
    18741915        /* Create a new item within current pane.  */ 
    1875         Lisp_Object item_name, enable, descrip, help; 
    1876  
     1916        Lisp_Object item_name, enable, descrip; 
    18771917        item_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_NAME]; 
    18781918        enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE]; 
    18791919        descrip 
    18801920          = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY]; 
    1881         help = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_HELP]; 
    18821921         
    18831922        if (NILP (item_name)) 
     
    19431982 
    19441983  /* Actually create the dialog.  */ 
    1945 #ifdef HAVE_DIALOGS 
     1984#if 0 
    19461985  dialog_id = widget_id_tick++; 
    19471986  menu = lw_create_widget (first_wv->name, "dialog", dialog_id, first_wv, 
    19481987                           f->output_data.w32->widget, 1, 0, 
    19491988                           dialog_selection_callback, 0); 
    1950   lw_modify_all_widgets (dialog_id, first_wv->contents, TRUE); 
     1989  lw_modify_all_widgets (dialog_id, first_wv->contents, True); 
    19511990#endif 
    19521991 
     
    19581997 
    19591998  /* Display the menu.  */ 
    1960 #ifdef HAVE_DIALOGS 
     1999#if 0 
    19612000  lw_pop_up_all_widgets (dialog_id); 
    19622001  popup_activated_flag = 1; 
     
    20142053     char *name; 
    20152054{ 
    2016   char *start = name; 
    2017  
    2018   /* Check if name string consists of only dashes ('-').  */ 
     2055  /* Check if name string consists of only dashes ('-') */ 
    20192056  while (*name == '-') name++; 
    2020   /* Separators can also be of the form "--:TripleSuperMegaEtched" 
    2021      or "--deep-shadow".  We don't implement them yet, se we just treat 
    2022      them like normal separators.  */ 
    2023   return (*name == '\0' || start + 2 == name); 
     2057  return (*name == '\0'); 
    20242058} 
    20252059 
     
    20372071  UINT fuFlags; 
    20382072  char *out_string; 
    2039   int return_value; 
    20402073 
    20412074  if (name_is_separator (wv->name)) 
    2042     { 
    2043       fuFlags = MF_SEPARATOR; 
    2044       out_string = NULL; 
    2045     } 
     2075    fuFlags = MF_SEPARATOR; 
    20462076  else  
    20472077    { 
     
    20692099          fuFlags = MF_OWNERDRAW | MF_DISABLED; 
    20702100        } 
    2071       /* Draw radio buttons and tickboxes. */ 
    2072       else if (wv->selected && (wv->button_type == BUTTON_TYPE_TOGGLE || 
    2073                            wv->button_type == BUTTON_TYPE_RADIO)) 
    2074         fuFlags |= MF_CHECKED; 
    2075       else 
    2076         fuFlags |= MF_UNCHECKED; 
    20772101    } 
    20782102 
     
    20802104    fuFlags = MF_POPUP; 
    20812105 
    2082   return_value = 
    2083     AppendMenu (menu, 
    2084                 fuFlags, 
    2085                 item != NULL ? (UINT) item : (UINT) wv->call_data, 
    2086                 out_string ); 
    2087  
    2088   /* This must be done after the menu item is created.  */ 
    2089   if ((fuFlags & MF_STRING) != 0) 
    2090     { 
    2091       HMODULE user32 = GetModuleHandle ("user32.dll"); 
    2092       FARPROC set_menu_item_info = GetProcAddress (user32, "SetMenuItemInfoA"); 
    2093  
    2094       if (set_menu_item_info) 
    2095         { 
    2096           MENUITEMINFO info; 
    2097           bzero (&info, sizeof (info)); 
    2098           info.cbSize = sizeof (info); 
    2099           info.fMask = MIIM_DATA; 
    2100  
    2101           /* Set help string for menu item.  */ 
    2102           info.dwItemData = (DWORD)wv->help; 
    2103  
    2104           if (wv->button_type == BUTTON_TYPE_RADIO) 
    2105             { 
    2106               /* CheckMenuRadioItem allows us to differentiate TOGGLE and 
    2107                  RADIO items, but is not available on NT 3.51 and earlier.  */ 
    2108               info.fMask |= MIIM_TYPE | MIIM_STATE; 
    2109               info.fType = MFT_RADIOCHECK | MFT_STRING; 
    2110               info.dwTypeData = out_string; 
    2111               info.fState = wv->selected ? MFS_CHECKED : MFS_UNCHECKED; 
    2112             } 
    2113  
    2114           set_menu_item_info (menu, 
    2115                               item != NULL ? (UINT) item : (UINT) wv->call_data, 
    2116                               FALSE, &info); 
    2117         } 
    2118     } 
    2119   return return_value; 
     2106  return AppendMenu (menu, 
     2107                     fuFlags, 
     2108                     item != NULL ? (UINT) item : (UINT) wv->call_data, 
     2109                     (fuFlags == MF_SEPARATOR) ? NULL: out_string ); 
    21202110} 
    21212111 
    21222112/* Construct native Windows menu(bar) based on widget_value tree.  */ 
    2123 int 
     2113static int 
    21242114fill_in_menu (HMENU menu, widget_value *wv) 
    21252115{ 
     
    21512141} 
    21522142 
    2153 int 
    2154 popup_activated () 
    2155 { 
    2156   /* popup_activated_flag not actually used on W32 */ 
    2157   return 0; 
    2158 } 
    2159  
    2160 /* Display help string for currently pointed to menu item. Not 
    2161    supported on NT 3.51 and earlier, as GetMenuItemInfo is not 
    2162    available. */ 
    2163 void 
    2164 w32_menu_display_help (HMENU menu, UINT item, UINT flags) 
    2165 { 
    2166   int pane = 0; /* TODO: Set this to pane number.  */ 
    2167  
    2168   HMODULE user32 = GetModuleHandle ("user32.dll"); 
    2169   FARPROC get_menu_item_info = GetProcAddress (user32, "GetMenuItemInfoA"); 
    2170  
    2171   if (get_menu_item_info) 
    2172     { 
    2173       extern Lisp_Object Qmenu_item; 
    2174       Lisp_Object *first_item; 
    2175       Lisp_Object pane_name; 
    2176       Lisp_Object menu_object; 
    2177       MENUITEMINFO info; 
    2178  
    2179       bzero (&info, sizeof (info)); 
    2180       info.cbSize = sizeof (info); 
    2181       info.fMask = MIIM_DATA; 
    2182       get_menu_item_info (menu, item, FALSE, &info); 
    2183  
    2184       first_item = XVECTOR (menu_items)->contents; 
    2185       if (EQ (first_item[0], Qt)) 
    2186         pane_name = first_item[MENU_ITEMS_PANE_NAME]; 
    2187       else if (EQ (first_item[0], Qquote)) 
    2188         /* This shouldn't happen, see w32_menu_show.  */ 
    2189         pane_name = build_string (""); 
    2190       else 
    2191         pane_name = first_item[MENU_ITEMS_ITEM_NAME]; 
    2192  
    2193       /* (menu-item MENU-NAME PANE-NUMBER)  */ 
    2194       menu_object = Fcons (Qmenu_item, 
    2195                            Fcons (pane_name, 
    2196                                   Fcons (make_number (pane), Qnil))); 
    2197  
    2198       show_help_echo (info.dwItemData ? 
    2199                       build_string ((char *) info.dwItemData) : Qnil, 
    2200                       Qnil, menu_object, make_number (item), 1); 
    2201     } 
    2202 } 
    2203  
    2204  
    2205  
    22062143#endif /* HAVE_MENUS */ 
    22072144