Below are diffs for changes we made to the files src/w32fns.c and
src/w32menu.c in emacs19.34 to make x-popup-menu work with a second
argument that is a list.  We did this because we wanted to have mouse
popup menus ala xemacs, and the existing code didn't seem to be working.
This is a quick and dirty hack, but has seemed to work fairly robustly
for a few months now.  We would like to see some version of it get
merged into the mainline version, if you see fit.

The format of the list argument is somewhat different than the
description in docstring for x-popup-menu.  The elements are either
strings or conses.  A string makes a menu entry which is a dimmed
title, unselectable.  A cons produces a selectable item.  Typically
the car is a string which is the label in the resulting menu entry and
the cdr is the value returned by x-popup-menu when the entry is
selected.  If the cdr is itself a list, it is used as to define a 
cascading popup, as if x-popup-menu had been called with this list as
its second argument.  If the car of an entry is not a string, then it is
t.  This means that the cdr is a cons where the car is used as the label
and the cdr as the return value, even if the cdr is a list.  In other
words, it is a way of getting a list return value instead of a cascading
popup.

diff -cr orig/w32fns.c hacked/w32fns.c
*** orig/w32fns.c Wed Aug 28 20:57:08 1996
--- hacked/w32fns.c Fri Aug 30 14:47:02 1996
***************
*** 2891,2897 ****
  	  switch (msg.message)
  	    {
  	    case WM_EMACS_CREATEWINDOW:
! 	      win32_createwindow ((struct frame *) msg.wParam);
  	      PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0);
  	      break;
  	    case WM_EMACS_CREATESCROLLBAR:
--- 2891,2903 ----
  	  switch (msg.message)
  	    {
  	    case WM_EMACS_CREATEWINDOW:
! 	      if (msg.lParam) {
! 		extern BOOL win32_popupmenu();
! 		win32_popupmenu(&msg);
! 		button_state = 0;
! 		one_win32_display_info.grabbed = 0;
! 	      } else
! 		win32_createwindow ((struct frame *) msg.wParam);
  	      PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0);
  	      break;
  	    case WM_EMACS_CREATESCROLLBAR:

diff -cr orig/w32menu.c hacked/w32menu.c
*** orig/w32menu.c Wed Aug 28 20:57:08 1996
--- hacked/w32menu.c Fri Aug 30 14:54:00 1996
***************
*** 72,79 ****
  static HMENU keymap_panes ();
  static HMENU single_keymap_panes ();
  static HMENU list_of_panes ();
- static HMENU list_of_items ();
- 
  static HMENU create_menu_items ();
  
  /* Initialize the menu_items structure if we haven't already done so.
--- 72,77 ----
***************
*** 609,615 ****
    Lisp_Object tail;
    HMENU hmenu;
    
!   hmenu = CreateMenu ();
    if (hmenu == NULL) return NULL;
    
    //    init_menu_items (lpmm);
--- 607,613 ----
    Lisp_Object tail;
    HMENU hmenu;
    
!   hmenu = CreatePopupMenu ();
    if (hmenu == NULL) return NULL;
    
    //    init_menu_items (lpmm);
***************
*** 620,635 ****
        HMENU new_hmenu;
  
        elt = Fcar (tail);
!       pane_name = Fcar (elt);
!       CHECK_STRING (pane_name, 0);
!       pane_data = Fcdr (elt);
!       CHECK_CONS (pane_data, 0);
  
-       new_hmenu = list_of_items (lpmm, pane_data);
-       if (new_hmenu == NULL) goto error;
- 
-       AppendMenu (hmenu, MF_POPUP, (UINT)new_hmenu,
- 		  (char *) XSTRING (pane_name)->data);
      }
  
    return (hmenu);
--- 618,654 ----
        HMENU new_hmenu;
  
        elt = Fcar (tail);
!       if (STRINGP (elt))
! 	add_menu_item (lpmm, hmenu, elt, 0, Qnil);
!       else if (NILP (elt))
! 	add_menu_item (lpmm, hmenu, elt, 0, Qnil);
!       else 
! 	{
! 	  int list_data_is_sub_menu = 1;
! 	  CHECK_CONS (elt, 0);
! 	  pane_name = Fcar (elt);
! 	  if (EQ (pane_name, Qt))
! 	    {
! 	      list_data_is_sub_menu = 0;
! 	      elt = Fcdr(elt);
! 	      CHECK_CONS (elt, 0);
! 	      pane_name = Fcar (elt);
! 	    }
! 	  CHECK_STRING (pane_name, 0);
! 	  pane_data = Fcdr (elt);
! 	  if (CONSP(pane_data) && list_data_is_sub_menu)
! 	    {
! 	      new_hmenu = list_of_panes (lpmm, pane_data);
! 	      if (new_hmenu == NULL) goto error;
! 	      AppendMenu (hmenu, MF_POPUP, (UINT)new_hmenu,
! 			  (char *) XSTRING (pane_name)->data);
! 	    }
! 	  else
! 	    {
! 	      add_menu_item (lpmm, hmenu, pane_name, 1, pane_data);
! 	    }
! 	}
  
      }
  
    return (hmenu);
***************
*** 640,676 ****
    return (NULL);
  }
  
- /* Push the items in a single pane defined by the alist PANE.  */
- 
- static HMENU 
- list_of_items (lpmm, pane)
-      menu_map * lpmm;
-      Lisp_Object pane;
- {
-   Lisp_Object tail, item, item1;
-   HMENU hmenu;
- 
-   hmenu = CreateMenu ();
-   if (hmenu == NULL) return NULL;
- 
-   for (tail = pane; !NILP (tail); tail = Fcdr (tail))
-     {
-       item = Fcar (tail);
-       if (STRINGP (item))
- 	add_menu_item (lpmm, hmenu, item, Qnil, Qnil);
-       else if (NILP (item))
- 	add_left_right_boundary ();
-       else
- 	{
- 	  CHECK_CONS (item, 0);
- 	  item1 = Fcar (item);
- 	  CHECK_STRING (item1, 1);
- 	  add_menu_item (lpmm, hmenu, item1, Qt, Fcdr (item));
- 	}
-     }
- 
-   return (hmenu);
- }
  
  
  HMENU 
--- 659,664 ----
***************
*** 747,756 ****
    else
      {
        /* We were given an old-fashioned menu.  */
!       title = Fcar (menu);
!       CHECK_STRING (title, 1);
! 	
!       hmenu = list_of_panes (lpmm, Fcdr (menu));
      }
    
    return (hmenu);
--- 735,741 ----
    else
      {
        /* We were given an old-fashioned menu.  */
!       hmenu = list_of_panes (lpmm, menu);
      }
    
    return (hmenu);
***************
*** 992,1027 ****
    return (event);
  }
  
- static Lisp_Object 
- get_list_of_items_event (pane, lpnum)
-      Lisp_Object pane;
-      int * lpnum;
- {
-   Lisp_Object tail, item, item1;
-   
-   for (tail = pane; !NILP (tail); tail = Fcdr (tail))
-     {
-       item = Fcar (tail);
-       if (STRINGP (item))
- 	{
- 	  if (-- (*lpnum) == 0) 
- 	    {
- 	      return (Qnil);
- 	    }
- 	}
-       else if (!NILP (item))
- 	{
- 	  if (--(*lpnum) == 0) 
- 	    {
- 	      CHECK_CONS (item, 0);
- 	      return (Fcdr (item));
- 	    }
- 	}
-     }
-   
-   return (Qnil);
- }
- 
  /* Push all the panes and items of a menu described by the
     alist-of-alists MENU.
     This handles old-fashioned calls to x-popup-menu.  */
--- 977,982 ----
***************
*** 1039,1053 ****
        Lisp_Object event;
  
        elt = Fcar (tail);
!       pane_data = Fcdr (elt);
!       CHECK_CONS (pane_data, 0);
! 
!       event = get_list_of_items_event (pane_data, lpnum);
! 
!       if (*lpnum <= 0) 
  	{
! 	  return (event);
  	}
      }
  
    return (Qnil);
--- 994,1029 ----
        Lisp_Object event;
  
        elt = Fcar (tail);
!       if (STRINGP (elt) || NILP (elt))
  	{
! 	  if (-- (*lpnum) == 0) 
! 	    {
! 	      return (Qnil);
! 	    }
  	}
+       else
+ 	{
+ 	  int list_data_is_sub_menu = 1;
+ 	  CHECK_CONS (elt, 0);
+ 	  if (EQ (Fcar(elt), Qt)) {
+ 	    list_data_is_sub_menu = 0;
+ 	    elt = Fcdr (elt);
+ 	    CHECK_CONS (elt, 0);
+ 	  }
+ 	  pane_data = Fcdr (elt);
+ 	  if (CONSP (pane_data) && list_data_is_sub_menu) {
+ 	    event = get_list_of_panes_event (pane_data, lpnum);
+ 	    if (*lpnum <= 0) 
+ 	      {
+ 		return (event);
+ 	      }
+ 	  } else {
+ 	    if (-- (*lpnum) == 0) 
+ 	      {
+ 		return (pane_data);
+ 	      }
+ 	  }
+ 	}
      }
  
    return (Qnil);
***************
*** 1096,1107 ****
    else
      {
        /* We were given an old-fashioned menu.  */
!       event = get_list_of_panes_event (Fcdr (menu), lpnum);
      }
  
    return (event);
  }
  
  DEFUN ("x-popup-menu", Fx_popup_menu, Sx_popup_menu, 2, 2, 0,
         "Pop up a deck-of-cards menu and return user's selection.\n\
  POSITION is a position specification.  This is either a mouse button event\n\
--- 1072,1092 ----
    else
      {
        /* We were given an old-fashioned menu.  */
!       event = get_list_of_panes_event (menu, lpnum);
      }
  
    return (event);
  }
  
+ typedef struct MY_POPUP {
+   int xpos;
+   int ypos;
+   Lisp_Object menu;
+   HMENU hmenu;
+   char **error_name;
+   Lisp_Object selection;
+ } MY_POPUP;
+ 
  DEFUN ("x-popup-menu", Fx_popup_menu, Sx_popup_menu, 2, 2, 0,
         "Pop up a deck-of-cards menu and return user's selection.\n\
  POSITION is a position specification.  This is either a mouse button event\n\
***************
*** 1240,1246 ****
    /* Display them in a menu.  */
    BLOCK_INPUT;
    
!   selection = win32menu_show (f, xpos, ypos, menu, &hmenu, &error_name);
    
    UNBLOCK_INPUT;
    
--- 1225,1243 ----
    /* Display them in a menu.  */
    BLOCK_INPUT;
    
!   {
!     MSG msg;
!     MY_POPUP x;
!     x.xpos = xpos;
!     x.ypos = ypos;
!     x.menu = menu;
!     x.hmenu = hmenu;
!     x.error_name = &error_name;
! 
!     PostThreadMessage (dwWinThreadId, WM_EMACS_CREATEWINDOW, (WPARAM)f, (LPARAM)&x);
!     GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
!     selection = x.selection;
!   }
    
    UNBLOCK_INPUT;
    
***************
*** 1253,1258 ****
--- 1250,1264 ----
    return selection;
  }
  
+ BOOL win32_popupmenu(msg)
+ MSG *msg;
+ {
+   FRAME_PTR f = (FRAME_PTR)msg->wParam;
+   MY_POPUP *x = (MY_POPUP *)msg->lParam;
+   x->selection = win32menu_show (f, x->xpos, x->ypos, x->menu, x->hmenu, x->error_name);
+   return *x->error_name ? FALSE : TRUE;
+ }
+ 
  DEFUN ("x-popup-dialog", Fx_popup_dialog, Sx_popup_dialog, 2, 2, 0,
         "Pop up a dialog box and return user's selection.\n\
  POSITION specifies which frame to use.\n\
***************
*** 1702,1715 ****
    
    /* Display the menu.  */
    menu_selection = TrackPopupMenu (hmenu,
! 				   0x10,
  				   pos.x, pos.y,
  				   0,
  				   FRAME_WIN32_WINDOW (f),
  				   NULL);
!   if (menu_selection == -1)
      {
!       *error = "Invalid menu specification";
        return Qnil;
      }
    
--- 1708,1727 ----
    
    /* Display the menu.  */
    menu_selection = TrackPopupMenu (hmenu,
! 				   TPM_RETURNCMD|TPM_RIGHTBUTTON,
  				   pos.x, pos.y,
  				   0,
  				   FRAME_WIN32_WINDOW (f),
  				   NULL);
!   if (menu_selection == 0)
      {
!       static char buf[100];
!       int e = GetLastError();
!       if (e != 5 /* EIO */)
! 	sprintf(&buf[0],"Invalid menu specification: %d", e);
!       else
! 	sprintf(&buf[0],"Menu aborted.");
!       *error = &buf[0];
        return Qnil;
      }
    
***************
*** 1719,1725 ****
  #if 1
    if (menu_selection > 0)
      {
!       return get_menu_event (menu, menu_selection);
      }
  #else
    if (menu_selection > 0 && menu_selection <= lpmm->menu_items_used)
--- 1731,1737 ----
  #if 1
    if (menu_selection > 0)
      {
!       return get_menu_event (menu, &menu_selection);
      }
  #else
    if (menu_selection > 0 && menu_selection <= lpmm->menu_items_used)
