/* NeXT/Open/GNUstep and MacOSX Cocoa menu and toolbar module.
- Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 2007-2011 Free Software Foundation, Inc.
This file is part of GNU Emacs.
/* This should be the first include, as it may set up #defines affecting
interpretation of even the system includes. */
-#include "config.h"
+#include <config.h>
#include <setjmp.h>
#include "lisp.h"
extern Lisp_Object QCtoggle, QCradio;
Lisp_Object Qdebug_on_next_call;
-extern Lisp_Object Voverriding_local_map, Voverriding_local_map_menu_flag,
- Qoverriding_local_map, Qoverriding_terminal_local_map;
+extern Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
extern long context_menu_value;
EmacsMenu *mainMenu, *svcsMenu, *dockMenu;
int
-popup_activated ()
+popup_activated (void)
{
return popup_activated_flag;
}
/* Save the frame's previous menu bar contents data */
if (previous_menu_items_used)
- bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items,
- previous_menu_items_used * sizeof (Lisp_Object));
+ memcpy (previous_items, &AREF (f->menu_bar_vector, 0),
+ previous_menu_items_used * sizeof (Lisp_Object));
/* parse stage 1: extract from lisp */
save_menu_items ();
menu_items = f->menu_bar_vector;
menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
- submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
- submenu_end = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
- submenu_n_panes = (int *) alloca (XVECTOR (items)->size * sizeof (int));
+ submenu_start = (int *) alloca (ASIZE (items) * sizeof (int *));
+ submenu_end = (int *) alloca (ASIZE (items) * sizeof (int *));
+ submenu_n_panes = (int *) alloca (ASIZE (items) * sizeof (int));
submenu_top_level_items
- = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
+ = (int *) alloca (ASIZE (items) * sizeof (int *));
init_menu_items ();
- for (i = 0; i < XVECTOR (items)->size; i += 4)
+ for (i = 0; i < ASIZE (items); i += 4)
{
Lisp_Object key, string, maps;
- key = XVECTOR (items)->contents[i];
- string = XVECTOR (items)->contents[i + 1];
- maps = XVECTOR (items)->contents[i + 2];
+ key = AREF (items, i);
+ string = AREF (items, i + 1);
+ maps = AREF (items, i + 2);
if (NILP (string))
break;
/* FIXME: this ALWAYS fails on Buffers menu items.. something
about their strings causes them to change every time, so we
double-check failures */
- if (!EQ (previous_items[i], XVECTOR (menu_items)->contents[i]))
+ if (!EQ (previous_items[i], AREF (menu_items, i)))
if (!(STRINGP (previous_items[i])
- && STRINGP (XVECTOR (menu_items)->contents[i])
+ && STRINGP (AREF (menu_items, i))
&& !strcmp (SDATA (previous_items[i]),
- SDATA (XVECTOR (menu_items)->contents[i]))))
+ SDATA (AREF (menu_items, i)))))
break;
if (i == previous_menu_items_used)
{
/* Parse stage 2a: now GC cannot happen during the lifetime of the
widget_value, so it's safe to store data from a Lisp_String */
wv = first_wv->contents;
- for (i = 0; i < XVECTOR (items)->size; i += 4)
+ for (i = 0; i < ASIZE (items); i += 4)
{
Lisp_Object string;
- string = XVECTOR (items)->contents[i + 1];
+ string = AREF (items, i + 1);
if (NILP (string))
break;
/* if (submenu && strcmp (submenuTitle, SDATA (string)))
continue; */
- wv->name = (char *) SDATA (string);
+ wv->name = SSDATA (string);
update_submenu_strings (wv->contents);
wv = wv->next;
}
/* check if no change.. this mechanism is a bit rough, but ready */
- n = XVECTOR (items)->size / 4;
+ n = ASIZE (items) / 4;
if (f == last_f && n_previous_strings == n)
{
for (i = 0; i<n; i++)
}
[menu clear];
- for (i = 0; i < XVECTOR (items)->size; i += 4)
+ for (i = 0; i < ASIZE (items); i += 4)
{
- string = XVECTOR (items)->contents[i + 1];
+ string = AREF (items, i + 1);
if (NILP (string))
break;
strncpy (previous_strings[i/4], SDATA (string), 10);
wv = xmalloc_widget_value ();
- wv->name = (char *) SDATA (string);
+ wv->name = SSDATA (string);
wv->value = 0;
wv->enabled = 1;
wv->button_type = BUTTON_TYPE_NONE;
{
/* but we need to make sure it will update on demand */
[svcsMenu setFrame: f];
- [svcsMenu setDelegate: svcsMenu];
}
else
#endif
}
-/* Utility (from macmenu.c): is this item a separator? */
-static int
-name_is_separator (name)
- const char *name;
-{
- const char *start = name;
-
- /* Check if name string consists of only dashes ('-'). */
- while (*name == '-') name++;
- /* Separators can also be of the form "--:TripleSuperMegaEtched"
- or "--deep-shadow". We don't implement them yet, se we just treat
- them like normal separators. */
- return (*name == '\0' || start + 2 == name);
-}
-
-
/* ==========================================================================
Menu: class implementation
NSMenuItem get ignored. For now we try to display a super-single letter
combo, and return the others as strings to be appended to the item title.
(This is signaled by setting keyEquivModMask to 0 for now.) */
--(NSString *)parseKeyEquiv: (char *)key
+-(NSString *)parseKeyEquiv: (const char *)key
{
- char *tpos = key;
+ const char *tpos = key;
keyEquivModMask = NSCommandKeyMask;
if (!key || !strlen (key))
return @"";
-
+
while (*tpos == ' ' || *tpos == '(')
tpos++;
if ((*tpos == 's') && (*(tpos+1) == '-'))
NSMenuItem *item;
widget_value *wv = (widget_value *)wvptr;
- if (name_is_separator (wv->name))
+ if (menu_separator_name_p (wv->name))
{
item = [NSMenuItem separatorItem];
[self addItem: item];
-(void)clear
{
int n;
-
+
for (n = [self numberOfItems]-1; n >= 0; n--)
{
NSMenuItem *item = [self itemAtIndex: n];
if ([[self window] isVisible])
[self sizeToFit];
#else
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_2
if ([self supermenu] == nil)
[self sizeToFit];
#endif
+#endif
}
/* adds an empty submenu and returns it */
-- (EmacsMenu *)addSubmenuWithTitle: (char *)title forFrame: (struct frame *)f
+- (EmacsMenu *)addSubmenuWithTitle: (const char *)title forFrame: (struct frame *)f
{
NSString *titleStr = [NSString stringWithUTF8String: title];
NSMenuItem *item = [self addItemWithTitle: titleStr
keymaps: (int)keymaps
{
EmacsView *view = FRAME_NS_VIEW (f);
+ NSEvent *e, *event;
+ long retVal;
+
/* p = [view convertPoint:p fromView: nil]; */
p.y = NSHeight ([view frame]) - p.y;
- NSEvent *e = [[view window] currentEvent];
- NSEvent *event = [NSEvent mouseEventWithType: NSRightMouseDown
- location: p
- modifierFlags: 0
- timestamp: [e timestamp]
- windowNumber: [[view window] windowNumber]
- context: [e context]
- eventNumber: 0/*[e eventNumber] */
- clickCount: 1
- pressure: 0];
- long retVal;
+ e = [[view window] currentEvent];
+ event = [NSEvent mouseEventWithType: NSRightMouseDown
+ location: p
+ modifierFlags: 0
+ timestamp: [e timestamp]
+ windowNumber: [[view window] windowNumber]
+ context: [e context]
+ eventNumber: 0/*[e eventNumber] */
+ clickCount: 1
+ pressure: 0];
context_menu_value = -1;
[NSMenu popUpContextMenu: self withEvent: event forView: view];
Lisp_Object
ns_menu_show (FRAME_PTR f, int x, int y, int for_click, int keymaps,
- Lisp_Object title, char **error)
+ Lisp_Object title, const char **error)
{
EmacsMenu *pmenu;
NSPoint p;
i = 0;
while (i < menu_items_used)
{
- if (EQ (XVECTOR (menu_items)->contents[i], Qnil))
+ if (EQ (AREF (menu_items, i), Qnil))
{
submenu_stack[submenu_depth++] = save_wv;
save_wv = prev_wv;
first_pane = 1;
i++;
}
- else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda))
+ else if (EQ (AREF (menu_items, i), Qlambda))
{
prev_wv = save_wv;
save_wv = submenu_stack[--submenu_depth];
first_pane = 0;
i++;
}
- else if (EQ (XVECTOR (menu_items)->contents[i], Qt)
+ else if (EQ (AREF (menu_items, i), Qt)
&& submenu_depth != 0)
i += MENU_ITEMS_PANE_LENGTH;
/* Ignore a nil in the item list.
It's meaningful only for dialog boxes. */
- else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))
+ else if (EQ (AREF (menu_items, i), Qquote))
i += 1;
- else if (EQ (XVECTOR (menu_items)->contents[i], Qt))
+ else if (EQ (AREF (menu_items, i), Qt))
{
/* Create a new pane. */
Lisp_Object pane_name, prefix;
- char *pane_string;
+ const char *pane_string;
pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
}
#endif
pane_string = (NILP (pane_name)
- ? "" : (char *) SDATA (pane_name));
+ ? "" : SSDATA (pane_name));
/* If there is just one top-level pane, put all its items directly
under the top-level menu. */
if (menu_items_n_panes == 1)
prev_wv->next = wv;
else
save_wv->contents = wv;
- wv->name = (char *) SDATA (item_name);
+ wv->name = SSDATA (item_name);
if (!NILP (descrip))
- wv->key = (char *) SDATA (descrip);
+ wv->key = SSDATA (descrip);
wv->value = 0;
/* If this item has a null value,
make the call_data null so that it won't display a box
when the mouse is on it. */
wv->call_data
- = !NILP (def) ? (void *) &XVECTOR (menu_items)->contents[i] : 0;
+ = !NILP (def) ? (void *) &AREF (menu_items, i) : 0;
wv->enabled = !NILP (enable);
if (NILP (type))
title = ENCODE_MENU_STRING (title);
#endif
- wv_title->name = (char *) SDATA (title);
+ wv_title->name = SSDATA (title);
wv_title->enabled = NO;
wv_title->button_type = BUTTON_TYPE_NONE;
wv_title->help = Qnil;
Under NS we just hide the toolbar until it might be needed again.
-------------------------------------------------------------------------- */
{
+ BLOCK_INPUT;
[[FRAME_NS_VIEW (f) toolbar] setVisible: NO];
+ FRAME_TOOLBAR_HEIGHT (f) = 0;
+ UNBLOCK_INPUT;
}
void
-------------------------------------------------------------------------- */
{
int i;
- EmacsToolbar *toolbar = [FRAME_NS_VIEW (f) toolbar];
+ EmacsView *view = FRAME_NS_VIEW (f);
+ NSWindow *window = [view window];
+ EmacsToolbar *toolbar = [view toolbar];
+ BLOCK_INPUT;
[toolbar clearActive];
/* update EmacsToolbar as in GtkUtils, build items list */
BOOL enabled_p = !NILP (TOOLPROP (TOOL_BAR_ITEM_ENABLED_P));
BOOL selected_p = !NILP (TOOLPROP (TOOL_BAR_ITEM_SELECTED_P));
int idx;
- int img_id;
+ ptrdiff_t img_id;
struct image *img;
Lisp_Object image;
Lisp_Object helpObj;
- char *helpText;
+ const char *helpText;
/* If image is a vector, choose the image according to the
button state. */
{
idx = -1;
}
+ helpObj = TOOLPROP (TOOL_BAR_ITEM_HELP);
+ if (NILP (helpObj))
+ helpObj = TOOLPROP (TOOL_BAR_ITEM_CAPTION);
+ helpText = NILP (helpObj) ? "" : SSDATA (helpObj);
+
/* Ignore invalid image specifications. */
if (!valid_image_p (image))
{
- NSLog (@"Invalid image for toolbar item");
+ /* Don't log anything, GNUS makes invalid images all the time. */
continue;
}
continue;
}
- helpObj = TOOLPROP (TOOL_BAR_ITEM_HELP);
- if (NILP (helpObj))
- helpObj = TOOLPROP (TOOL_BAR_ITEM_CAPTION);
- helpText = NILP (helpObj) ? "" : (char *)SDATA (helpObj);
-
[toolbar addDisplayItemWithImage: img->pixmap idx: i helpText: helpText
enabled: enabled_p];
#undef TOOLPROP
[newDict release];
}
+ FRAME_TOOLBAR_HEIGHT (f) =
+ NSHeight ([window frameRectForContentRect: NSMakeRect (0, 0, 0, 0)])
+ - FRAME_NS_TITLEBAR_HEIGHT (f);
+ UNBLOCK_INPUT;
}
}
- (void) addDisplayItemWithImage: (EmacsImage *)img idx: (int)idx
- helpText: (char *)help enabled: (BOOL)enabled
+ helpText: (const char *)help enabled: (BOOL)enabled
{
/* 1) come up w/identifier */
NSString *identifier
[textField setEditable: NO];
[textField setSelectable: NO];
- [textField setBordered: YES];
- [textField setBezeled: YES];
+ [textField setBordered: NO];
+ [textField setBezeled: NO];
[textField setDrawsBackground: YES];
win = [[NSWindow alloc]
styleMask: 0
backing: NSBackingStoreBuffered
defer: YES];
+ [win setHasShadow: YES];
[win setReleasedWhenClosed: NO];
[win setDelegate: self];
[[win contentView] addSubview: textField];
- (void) setText: (char *)text
{
NSString *str = [NSString stringWithUTF8String: text];
- NSRect r = [textField frame];
- NSSize textSize = [str sizeWithAttributes:
- [NSDictionary dictionaryWithObject: [[textField font] screenFont]
- forKey: NSFontAttributeName]];
- NSSize padSize = [[[textField font] screenFont]
- boundingRectForFont].size;
-
- r.size.width = textSize.width + padSize.width/2;
- r.size.height = textSize.height + padSize.height/2;
- [textField setFrame: r];
+ NSRect r = [textField frame];
+ NSSize tooltipDims;
+
[textField setStringValue: str];
+ tooltipDims = [[textField cell] cellSize];
+
+ r.size.width = tooltipDims.width;
+ r.size.height = tooltipDims.height;
+ [textField setFrame: r];
}
- (void) showAtX: (int)x Y: (int)y for: (int)seconds
ns_popup_dialog (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
{
id dialog;
- Lisp_Object window, tem;
+ Lisp_Object window, tem, title;
struct frame *f;
NSPoint p;
BOOL isQ;
NSTRACE (x-popup-dialog);
-
+
check_ns ();
isQ = NILP (header);
p.x = (int)f->left_pos + ((int)FRAME_COLUMN_WIDTH (f) * f->text_cols)/2;
p.y = (int)f->top_pos + (FRAME_LINE_HEIGHT (f) * f->text_lines)/2;
+ title = Fcar (contents);
+ CHECK_STRING (title);
+
+ if (NILP (Fcar (Fcdr (contents))))
+ /* No buttons specified, add an "Ok" button so users can pop down
+ the dialog. */
+ contents = Fcons (title, Fcons (Fcons (build_string ("Ok"), Qt), Qnil));
+
BLOCK_INPUT;
dialog = [[EmacsDialogPanel alloc] initFromContents: contents
isQuestion: isQ];
[cell setCellAttribute: NSCellIsInsetButton to: 8];
[cell setBezelStyle: NSRoundedBezelStyle];
- matrix = [[NSMatrix alloc] initWithFrame: contentRect
- mode: NSHighlightModeMatrix
- prototype: cell
- numberOfRows: 0
+ matrix = [[NSMatrix alloc] initWithFrame: contentRect
+ mode: NSHighlightModeMatrix
+ prototype: cell
+ numberOfRows: 0
numberOfColumns: 1];
[[self contentView] addSubview: matrix];
[matrix release];
- addButton: (char *)str value: (Lisp_Object)val row: (int)row
{
id cell;
-
+
if (row >= rows)
{
[matrix addRow];
- addString: (char *)str row: (int)row
{
id cell;
-
+
if (row >= rows)
{
[matrix addRow];
EMACS_INT seltag;
sellist = [sender selectedCells];
- if ([sellist count]<1)
+ if ([sellist count]<1)
return self;
seltag = [[sellist objectAtIndex: 0] tag];
- (Lisp_Object)runDialogAt: (NSPoint)p
{
NSInteger ret;
- extern EMACS_TIME timer_check (int do_it_now); /* TODO: add to a header */
/* initiate a session that will be ended by pop_down_menu */
popupSession = [NSApp beginModalSessionForWindow: self];
{
/* Run this for timers.el, indep of atimers; might not return.
TODO: use return value to avoid calling every iteration. */
- timer_check (1);
+ timer_check ();
[NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.1]];
}
DEFUN ("ns-reset-menu", Fns_reset_menu, Sns_reset_menu, 0, 0, 0,
doc: /* Cause the NS menu to be re-calculated. */)
- ()
+ (void)
{
set_frame_menubar (SELECTED_FRAME (), 1, 0);
return Qnil;
If the user gets rid of the dialog box without making a valid choice,
for instance using the window manager, then this produces a quit and
`x-popup-dialog' does not return. */)
- (position, contents, header)
- Lisp_Object position, contents, header;
+ (Lisp_Object position, Lisp_Object contents, Lisp_Object header)
{
return ns_popup_dialog (position, contents, header);
}
DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p, 0, 0, 0,
doc: /* Return t if a menu or popup dialog is active. */)
- ()
+ (void)
{
return popup_activated () ? Qt : Qnil;
}
========================================================================== */
void
-syms_of_nsmenu ()
+syms_of_nsmenu (void)
{
defsubr (&Sx_popup_dialog);
defsubr (&Sns_reset_menu);
defsubr (&Smenu_or_popup_active_p);
- Qdebug_on_next_call = intern ("debug-on-next-call");
+ Qdebug_on_next_call = intern_c_string ("debug-on-next-call");
staticpro (&Qdebug_on_next_call);
}
-
-// arch-tag: 75773656-52e5-4c44-a398-47bd87b32619