/* Menu support for GNU Emacs on the for Mac OS.
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include "dispextern.h"
#define POPUP_SUBMENU_ID 235
+#define MIN_POPUP_SUBMENU_ID 512
#define MIN_MENU_ID 256
#define MIN_SUBMENU_ID 1
char* name;
/* value (meaning depend on widget type) */
char* value;
- /* keyboard equivalent. no implications for XtTranslations */
+ /* keyboard equivalent. no implications for XtTranslations */
char* key;
/* Help string or nil if none.
GC finds this string through the frame's menu_bar_vector
static void list_of_panes ();
static void list_of_items ();
-static void fill_submenu (MenuHandle, widget_value *, int);
+static void fill_submenu (MenuHandle, widget_value *);
static void fill_menubar (widget_value *);
\f
Xt on behalf of one of the widget sets. */
static int popup_activated_flag;
+/* Index of the next submenu */
+static int submenu_id;
+
static int next_menubar_widget_id;
/* This is set nonzero after the user activates the menu bar, and set
\f
/* This is a subroutine of single_keymap_panes that handles one
keymap entry.
- KEY is a key in a keymap and ITEM is its binding.
+ KEY is a key in a keymap and ITEM is its binding.
PENDING_MAPS_PTR points to a list of keymaps waiting to be made into
separate panes.
If NOTREAL is nonzero, only check for equivalent key bindings, don't
Lisp_Object map, item_string, enabled;
struct gcpro gcpro1, gcpro2;
int res;
-
+
/* Parse the menu item and leave the result in item_properties. */
GCPRO2 (key, item);
res = parse_menu_item (item, notreal, 0);
return; /* Not a menu item. */
map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP];
-
+
if (notreal)
{
/* We don't want to make a menu, just traverse the keymaps to
}
enabled = XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE];
- item_string = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME];
+ item_string = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME];
if (!NILP (map) && SREF (item_string, 0) == '@')
{
CHECK_LIVE_WINDOW (window);
f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
- xpos = (FONT_WIDTH (FRAME_FONT (f))
- * XFASTINT (XWINDOW (window)->left));
- ypos = (FRAME_LINE_HEIGHT (f)
- * XFASTINT (XWINDOW (window)->top));
+ xpos = WINDOW_LEFT_EDGE_X (XWINDOW (window));
+ ypos = WINDOW_TOP_EDGE_Y (XWINDOW (window));
}
else
/* ??? Not really clean; should be CHECK_WINDOW_OR_FRAME,
keymaps = 0;
}
-
+
if (NILP (position))
{
discard_menu_items ();
But first we recompute the menu bar contents (the whole tree).
This way we can safely execute Lisp code. */
-
+
void
x_activate_menubar (f)
FRAME_PTR f;
int j;
struct input_event buf;
Lisp_Object frame;
+ EVENT_INIT (buf);
XSETFRAME (frame, f);
buf.kind = MENU_BAR_EVENT;
first_wv = wv;
save_wv = 0;
prev_wv = 0;
-
+
/* Loop over all panes and items made during this call
and construct a tree of widget_value objects.
Ignore the panes and items made by previous calls to
#endif /* not HAVE_MULTILINGUAL_MENU */
wv = xmalloc_widget_value ();
- if (prev_wv)
+ if (prev_wv)
prev_wv->next = wv;
else
save_wv->contents = wv;
break;
wv = single_submenu (key, string, maps);
- if (prev_wv)
+ if (prev_wv)
prev_wv->next = wv;
else
first_wv->contents = wv;
This value just has to be different from small integers. */
wv->call_data = (void *) (EMACS_INT) (-1);
- if (prev_wv)
+ if (prev_wv)
prev_wv->next = wv;
else
first_wv->contents = wv;
DisposeMenu (menu);
menu = GetMenuHandle (++i);
}
-
+
i = MIN_SUBMENU_ID;
menu = GetMenuHandle (i);
while (menu != NULL)
}
fill_menubar (first_wv->contents);
-
+
DrawMenuBar ();
-
+
free_menubar_widget_value_tree (first_wv);
UNBLOCK_INPUT;
char **error;
{
int i;
+ UInt32 refcon;
+ int menu_item_choice;
int menu_item_selection;
MenuHandle menu;
Point pos;
wv->help = Qnil;
first_wv = wv;
first_pane = 1;
-
+
/* Loop over all panes and items, filling in the tree. */
i = 0;
while (i < menu_items_used)
#endif /* not HAVE_MULTILINGUAL_MENU */
wv = xmalloc_widget_value ();
- if (prev_wv)
+ if (prev_wv)
prev_wv->next = wv;
- else
+ else
save_wv->contents = wv;
wv->name = (char *) SDATA (item_name);
if (!NILP (descrip))
/* Actually create the menu. */
menu = NewMenu (POPUP_SUBMENU_ID, "\p");
- fill_submenu (menu, first_wv->contents, 0);
+ submenu_id = MIN_POPUP_SUBMENU_ID;
+ fill_submenu (menu, first_wv->contents);
/* Adjust coordinates to be root-window-relative. */
pos.h = x;
LocalToGlobal (&pos);
/* No selection has been chosen yet. */
+ menu_item_choice = 0;
menu_item_selection = 0;
InsertMenu (menu, -1);
/* Display the menu. */
- menu_item_selection = LoWord (PopUpMenuSelect (menu, pos.v, pos.h, 0));
+ menu_item_choice = PopUpMenuSelect (menu, pos.v, pos.h, 0);
+ menu_item_selection = LoWord (menu_item_choice);
+
+ /* Get the refcon to find the correct item*/
+ if (menu_item_selection)
+ {
+ menu = GetMenuHandle (HiWord (menu_item_choice));
+ if (menu) {
+ GetMenuItemRefCon (menu, menu_item_selection, &refcon);
+ }
+ }
- DeleteMenu (POPUP_SUBMENU_ID);
-
#if 0
/* Clean up extraneous mouse events which might have been generated
during the call. */
contents. */
free_menubar_widget_value_tree (first_wv);
+ /* delete all menus */
+ {
+ int i = MIN_POPUP_SUBMENU_ID;
+ MenuHandle submenu = GetMenuHandle (i);
+ while (menu != NULL)
+ {
+ DeleteMenu (i);
+ DisposeMenu (menu);
+ menu = GetMenuHandle (++i);
+ }
+ }
+
+ DeleteMenu (POPUP_SUBMENU_ID);
DisposeMenu (menu);
/* Find the selected item, and its pane, to return
if (menu_item_selection != 0)
{
Lisp_Object prefix, entry;
- int j = 1;
prefix = entry = Qnil;
i = 0;
prefix
= XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
i += MENU_ITEMS_PANE_LENGTH;
- j += 2;
}
/* Ignore a nil in the item list.
It's meaningful only for dialog boxes. */
{
entry
= XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE];
- if (menu_item_selection == j)
+ if ((int) (EMACS_INT) refcon == i)
{
if (keymaps != 0)
{
return entry;
}
i += MENU_ITEMS_ITEM_LENGTH;
- j++;
}
}
}
SInt16 part_code;
int control_part_code;
Point mouse;
-
+
dialog_name = wv->name;
nb_buttons = dialog_name[1] - '0';
left_count = nb_buttons - (dialog_name[4] - '0');
button_labels = (char **) alloca (sizeof (char *) * nb_buttons);
ref_cons = (UInt32 *) alloca (sizeof (UInt32) * nb_buttons);
-
+
wv = wv->contents;
prompt = (char *) alloca (strlen (wv->value) + 1);
strcpy (prompt, wv->value);
#else
SetPort (window_ptr);
#endif
-
+
TextFont (0);
/* Left and right margins in the dialog are 13 pixels each.*/
dialog_width = 14;
#else
SetPort (window_ptr);
#endif
-
+
TextFont (0);
MoveTo (13, 29);
}
DisposeWindow (window_ptr);
-
+
return i;
}
pane_name = XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_NAME];
prefix = XVECTOR (menu_items)->contents[MENU_ITEMS_PANE_PREFIX];
pane_string = (NILP (pane_name)
- ? "" : (char *) SDATA (pane_name));
+ ? "" : (char *) SDATA (pane_name));
prev_wv = xmalloc_widget_value ();
prev_wv->value = pane_string;
if (keymaps && !NILP (prefix))
prev_wv->name = "message";
prev_wv->help = Qnil;
first_wv = prev_wv;
-
+
/* Loop over all panes and items, filling in the tree. */
i = MENU_ITEMS_PANE_LENGTH;
while (i < menu_items_used)
{
-
+
/* Create a new item within current pane. */
Lisp_Object item_name, enable, descrip, help;
descrip
= XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY];
help = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_HELP];
-
+
if (NILP (item_name))
{
free_menubar_widget_value_tree (first_wv);
}
static void
-add_menu_item (MenuHandle menu, widget_value *wv, int submenu, int indent,
+add_menu_item (MenuHandle menu, widget_value *wv, int submenu,
int force_disable)
{
Str255 item_name;
if (name_is_separator (wv->name))
AppendMenu (menu, "\p-");
- else
+ else
{
AppendMenu (menu, "\pX");
-
+
#if TARGET_API_MAC_CARBON
pos = CountMenuItems (menu);
#else
#endif
strcpy (item_name, "");
- for (i = 0; i < indent; i++)
- strncat (item_name, " ", 255);
strncat (item_name, wv->name, 255);
if (wv->key != NULL)
{
SetMenuItemHierarchicalID (menu, pos, submenu);
}
-static int submenu_id;
-
/* Construct native Mac OS menubar based on widget_value tree. */
static void
-fill_submenu (MenuHandle menu, widget_value *wv, int indent)
+fill_submenu (MenuHandle menu, widget_value *wv)
{
for ( ; wv != NULL; wv = wv->next)
if (wv->contents)
{
- add_menu_item (menu, wv, NULL, indent, 1);
-
- fill_submenu (menu, wv->contents, indent + 1);
+ int cur_submenu = submenu_id++;
+ MenuHandle submenu = NewMenu (cur_submenu, "\pX");
+ fill_submenu (submenu, wv->contents);
+ InsertMenu (submenu, -1);
+ add_menu_item (menu, wv, cur_submenu, 0);
}
else
- add_menu_item (menu, wv, NULL, indent, 0);
+ add_menu_item (menu, wv, NULL, 0);
}
for ( ; wv != NULL; wv = wv->next)
if (wv->contents)
{
- MenuHandle submenu = NewMenu (submenu_id, "\pX");
- fill_submenu (submenu, wv->contents, 0);
+ int cur_submenu = submenu_id++;
+ MenuHandle submenu = NewMenu (cur_submenu, "\pX");
+ fill_submenu (submenu, wv->contents);
InsertMenu (submenu, -1);
- add_menu_item (menu, wv, submenu_id, 0, 0);
- submenu_id++;
+ add_menu_item (menu, wv, cur_submenu, 0);
}
else
- add_menu_item (menu, wv, NULL, 0, 0);
+ add_menu_item (menu, wv, NULL, 0);
}
/* Construct native Mac OS menubar based on widget_value tree. */
{
MenuHandle menu;
Str255 title;
-
+
strncpy (title, wv->name, 255);
title[255] = 0;
c2pstr (title);
if (wv->contents)
fill_menu (menu, wv->contents);
-
+
InsertMenu (menu, 0);
}
}
defsubr (&Sx_popup_dialog);
#endif
}
+
+/* arch-tag: 40b2c6c7-b8a9-4a49-b930-1b2707184cce
+ (do not change this comment) */