#include <signal.h>
#include <unistd.h>
#include <setjmp.h>
+#include <c-strcase.h>
+#include <ftoastr.h>
#include "lisp.h"
#include "blockinput.h"
#include "window.h"
#include "keyboard.h"
-
+#include "buffer.h"
#include "font.h"
/* call tracing */
static struct frame *ns_updating_frame;
static NSView *focus_view = NULL;
static int ns_window_num = 0;
+#ifdef NS_IMPL_GNUSTEP
static NSRect uRect;
+#endif
static BOOL gsaved = NO;
BOOL ns_in_resize = NO;
static BOOL ns_fake_keydown = NO;
static NSTimer *fd_entry = nil;
static NSTimer *scroll_repeat_entry = nil;
static fd_set select_readfds, t_readfds;
-static struct timeval select_timeout;
static int select_nfds;
static NSAutoreleasePool *outerpool;
static struct input_event *emacs_event = NULL;
static NSMutableArray *ns_pending_files, *ns_pending_service_names,
*ns_pending_service_args;
static BOOL inNsSelect = 0;
+static BOOL ns_do_open_file = NO;
/* Convert modifiers in a NeXTstep event to emacs style modifiers. */
#define NS_FUNCTION_KEY_MASK 0x800000
}
-void
-ns_init_paths (void)
-/* --------------------------------------------------------------------------
- Used to allow emacs to find its resources under Emacs.app
- Called from emacs.c at startup.
- -------------------------------------------------------------------------- */
+const char *
+ns_etc_directory (void)
+/* If running as a self-contained app bundle, return as a string the
+ filename of the etc directory, if present; else nil. */
+{
+ NSBundle *bundle = [NSBundle mainBundle];
+ NSString *resourceDir = [bundle resourcePath];
+ NSString *resourcePath;
+ NSFileManager *fileManager = [NSFileManager defaultManager];
+ BOOL isDir;
+
+ resourcePath = [resourceDir stringByAppendingPathComponent: @"etc"];
+ if ([fileManager fileExistsAtPath: resourcePath isDirectory: &isDir])
+ {
+ if (isDir) return [resourcePath UTF8String];
+ }
+ return NULL;
+}
+
+
+const char *
+ns_exec_path (void)
+/* If running as a self-contained app bundle, return as a path string
+ the filenames of the libexec and bin directories, ie libexec:bin.
+ Otherwise, return nil.
+ Normally, Emacs does not add its own bin/ directory to the PATH.
+ However, a self-contained NS build has a different layout, with
+ bin/ and libexec/ subdirectories in the directory that contains
+ Emacs.app itself.
+ We put libexec first, because init_callproc_1 uses the first
+ element to initialize exec-directory. An alternative would be
+ for init_callproc to check for invocation-directory/libexec.
+*/
{
NSBundle *bundle = [NSBundle mainBundle];
- NSString *binDir = [bundle bundlePath], *resourceDir = [bundle resourcePath];
+ NSString *resourceDir = [bundle resourcePath];
+ NSString *binDir = [bundle bundlePath];
NSString *resourcePath, *resourcePaths;
NSRange range;
- BOOL onWindows = NO; /* how do I determine this? */
- NSString *pathSeparator = onWindows ? @";" : @":";
+ NSString *pathSeparator = [NSString stringWithFormat: @"%c", SEPCHAR];
NSFileManager *fileManager = [NSFileManager defaultManager];
+ NSArray *paths;
+ NSEnumerator *pathEnum;
BOOL isDir;
-/*NSLog (@"ns_init_paths: '%@'\n%@\n", [[NSBundle mainBundle] bundlePath], [[NSBundle mainBundle] resourcePath]); */
- /* get bindir from base */
range = [resourceDir rangeOfString: @"Contents"];
if (range.location != NSNotFound)
{
#endif
}
- /* the following based on Andrew Choi's init_mac_osx_environment () */
- if (!getenv ("EMACSLOADPATH"))
- {
- NSArray *paths = [resourceDir stringsByAppendingPaths:
- [NSArray arrayWithObjects:
- @"site-lisp", @"lisp", @"leim", nil]];
- NSEnumerator *pathEnum = [paths objectEnumerator];
- resourcePaths = @"";
- while (resourcePath = [pathEnum nextObject])
- {
- if ([fileManager fileExistsAtPath: resourcePath isDirectory: &isDir])
- if (isDir)
- {
- if ([resourcePaths length] > 0)
- resourcePaths
- = [resourcePaths stringByAppendingString: pathSeparator];
- resourcePaths
- = [resourcePaths stringByAppendingString: resourcePath];
- }
- }
- if ([resourcePaths length] > 0)
- setenv ("EMACSLOADPATH", [resourcePaths UTF8String], 1);
-/*NSLog (@"loadPath: '%@'\n", resourcePaths); */
- }
-
- if (!getenv ("EMACSPATH"))
- {
- NSArray *paths = [binDir stringsByAppendingPaths:
- [NSArray arrayWithObjects: @"bin",
- @"lib-exec", nil]];
- NSEnumerator *pathEnum = [paths objectEnumerator];
- resourcePaths = @"";
- while (resourcePath = [pathEnum nextObject])
- {
- if ([fileManager fileExistsAtPath: resourcePath isDirectory: &isDir])
- if (isDir)
- {
- if ([resourcePaths length] > 0)
- resourcePaths
- = [resourcePaths stringByAppendingString: pathSeparator];
- resourcePaths
- = [resourcePaths stringByAppendingString: resourcePath];
- }
- }
- if ([resourcePaths length] > 0)
- setenv ("EMACSPATH", [resourcePaths UTF8String], 1);
- }
-
- resourcePath = [resourceDir stringByAppendingPathComponent: @"etc"];
- if ([fileManager fileExistsAtPath: resourcePath isDirectory: &isDir])
- {
- if (isDir)
- {
- if (!getenv ("EMACSDATA"))
- setenv ("EMACSDATA", [resourcePath UTF8String], 1);
- if (!getenv ("EMACSDOC"))
- setenv ("EMACSDOC", [resourcePath UTF8String], 1);
- }
- }
+ paths = [binDir stringsByAppendingPaths:
+ [NSArray arrayWithObjects: @"libexec", @"bin", nil]];
+ pathEnum = [paths objectEnumerator];
+ resourcePaths = @"";
- if (!getenv ("INFOPATH"))
+ while ((resourcePath = [pathEnum nextObject]))
{
- resourcePath = [resourceDir stringByAppendingPathComponent: @"info"];
if ([fileManager fileExistsAtPath: resourcePath isDirectory: &isDir])
if (isDir)
- setenv ("INFOPATH", [[resourcePath stringByAppendingString: @":"]
- UTF8String], 1);
- /* Note, extra colon needed to cause merge w/later user additions. */
+ {
+ if ([resourcePaths length] > 0)
+ resourcePaths
+ = [resourcePaths stringByAppendingString: pathSeparator];
+ resourcePaths
+ = [resourcePaths stringByAppendingString: resourcePath];
+ }
}
+ if ([resourcePaths length] > 0) return [resourcePaths UTF8String];
+
+ return NULL;
}
-static int
-timeval_subtract (struct timeval *result, struct timeval x, struct timeval y)
-/* --------------------------------------------------------------------------
- Subtract the `struct timeval' values X and Y, storing the result in RESULT.
- Return 1 if the difference is negative, otherwise 0.
- -------------------------------------------------------------------------- */
+const char *
+ns_load_path (void)
+/* If running as a self-contained app bundle, return as a path string
+ the filenames of the site-lisp, lisp and leim directories.
+ Ie, site-lisp:lisp:leim. Otherwise, return nil. */
{
- /* Perform the carry for the later subtraction by updating y.
- This is safer because on some systems
- the tv_sec member is unsigned. */
- if (x.tv_usec < y.tv_usec)
- {
- int nsec = (y.tv_usec - x.tv_usec) / 1000000 + 1;
- y.tv_usec -= 1000000 * nsec;
- y.tv_sec += nsec;
- }
- if (x.tv_usec - y.tv_usec > 1000000)
+ NSBundle *bundle = [NSBundle mainBundle];
+ NSString *resourceDir = [bundle resourcePath];
+ NSString *resourcePath, *resourcePaths;
+ NSString *pathSeparator = [NSString stringWithFormat: @"%c", SEPCHAR];
+ NSFileManager *fileManager = [NSFileManager defaultManager];
+ BOOL isDir;
+ NSArray *paths = [resourceDir stringsByAppendingPaths:
+ [NSArray arrayWithObjects:
+ @"site-lisp", @"lisp", @"leim", nil]];
+ NSEnumerator *pathEnum = [paths objectEnumerator];
+ resourcePaths = @"";
+
+ /* Hack to skip site-lisp. */
+ if (no_site_lisp) resourcePath = [pathEnum nextObject];
+
+ while ((resourcePath = [pathEnum nextObject]))
{
- int nsec = (y.tv_usec - x.tv_usec) / 1000000;
- y.tv_usec += 1000000 * nsec;
- y.tv_sec -= nsec;
+ if ([fileManager fileExistsAtPath: resourcePath isDirectory: &isDir])
+ if (isDir)
+ {
+ if ([resourcePaths length] > 0)
+ resourcePaths
+ = [resourcePaths stringByAppendingString: pathSeparator];
+ resourcePaths
+ = [resourcePaths stringByAppendingString: resourcePath];
+ }
}
+ if ([resourcePaths length] > 0) return [resourcePaths UTF8String];
- /* Compute the time remaining to wait. tv_usec is certainly positive. */
- result->tv_sec = x.tv_sec - y.tv_sec;
- result->tv_usec = x.tv_usec - y.tv_usec;
-
- /* Return indication of whether the result should be considered negative. */
- return x.tv_sec < y.tv_sec;
+ return NULL;
}
static void
Blocking timer utility used by ns_ring_bell
-------------------------------------------------------------------------- */
{
- struct timeval wakeup;
-
- EMACS_GET_TIME (wakeup);
-
- /* Compute time to wait until, propagating carry from usecs. */
- wakeup.tv_usec += usecs;
- wakeup.tv_sec += (wakeup.tv_usec / 1000000);
- wakeup.tv_usec %= 1000000;
+ EMACS_TIME wakeup = add_emacs_time (current_emacs_time (),
+ make_emacs_time (0, usecs * 1000));
/* Keep waiting until past the time wakeup. */
while (1)
{
- struct timeval timeout;
-
- EMACS_GET_TIME (timeout);
-
- /* In effect, timeout = wakeup - timeout.
- Break if result would be negative. */
- if (timeval_subtract (&timeout, wakeup, timeout))
+ EMACS_TIME timeout, now = current_emacs_time ();
+ if (EMACS_TIME_LE (wakeup, now))
break;
+ timeout = sub_emacs_time (wakeup, now);
/* Try to wait that long--but we might wake up sooner. */
- select (0, NULL, NULL, NULL, &timeout);
+ pselect (0, NULL, NULL, NULL, &timeout, NULL);
}
}
: dpyinfo->x_focus_frame);
if (!FRAME_LIVE_P (dpyinfo->x_highlight_frame))
{
- FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame) = Qnil;
+ FSET (dpyinfo->x_focus_frame, focus_frame, Qnil);
dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame;
}
}
NSView *view = FRAME_NS_VIEW (f);
struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f);
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
- NSTRACE (x_destroy_window);
+ NSTRACE (x_free_frame_resources);
check_ns ();
[(EmacsView *)view setWindowClosing: YES]; /* may not have been informed */
hlinfo->mouse_face_mouse_frame = 0;
}
- xfree (f->output_data.ns);
-
if (f->output_data.ns->miniimage != nil)
[f->output_data.ns->miniimage release];
[[view window] close];
[view release];
+ xfree (f->output_data.ns);
+
UNBLOCK_INPUT;
}
-------------------------------------------------------------------------- */
{
EmacsView *view = FRAME_NS_VIEW (f);
- EmacsToolbar *toolbar = [view toolbar];
NSWindow *window = [view window];
NSRect wr = [window frame];
int tb = FRAME_EXTERNAL_TOOL_BAR (f);
{
color_table->size = NS_COLOR_CAPACITY;
color_table->avail = 1; /* skip idx=0 as marker */
- color_table->colors
- = (NSColor **)xmalloc (color_table->size * sizeof (NSColor *));
+ color_table->colors = xmalloc (color_table->size * sizeof (NSColor *));
color_table->colors[0] = nil;
color_table->empty_indices = [[NSMutableSet alloc] init];
}
[scanner scanFloat: &b];
}
else if (!strncmp(name, "rgb:", 4)) /* A newer X11 format -- rgb:r/g/b */
- {
- strncpy (hex, name + 4, 19);
- hex[19] = '\0';
- scaling = (strlen(hex) - 2) / 3;
- }
+ scaling = (snprintf (hex, sizeof hex, "%s", name + 4) - 2) / 3;
else if (name[0] == '#') /* An old X11 format; convert to newer */
{
int len = (strlen(name) - 1);
int start = (len % 3 == 0) ? 1 : len / 4 + 1;
int i;
scaling = strlen(name+start) / 3;
- for (i=0; i<3; i++) {
- strncpy(hex + i * (scaling + 1), name + start + i * scaling, scaling);
- hex[(i+1) * (scaling + 1) - 1] = '/';
- }
+ for (i = 0; i < 3; i++)
+ sprintf (hex + i * (scaling + 1), "%.*s/", scaling,
+ name + start + i * scaling);
hex[3 * (scaling + 1) - 1] = '\0';
}
}
-static NSColor *
-ns_get_color_default (const char *name, NSColor *dflt)
-/* --------------------------------------------------------------------------
- Parse a color or use a default value
- -------------------------------------------------------------------------- */
-{
- NSColor * col;
-
- if (ns_get_color (name, &col))
- return dflt;
- else
- return col;
-}
-
-
int
ns_lisp_to_color (Lisp_Object color, NSColor **col)
/* --------------------------------------------------------------------------
{
NSTRACE (ns_lisp_to_color);
if (STRINGP (color))
- return ns_get_color (SDATA (color), col);
+ return ns_get_color (SSDATA (color), col);
else if (SYMBOLP (color))
- return ns_get_color (SDATA (SYMBOL_NAME (color)), col);
+ return ns_get_color (SSDATA (SYMBOL_NAME (color)), col);
return 1;
}
{
id view;
NSPoint position;
- int xchar, ychar;
Lisp_Object frame, tail;
struct frame *f;
struct ns_display_info *dpyinfo;
}
-void
+static void
ns_define_frame_cursor (struct frame *f, Cursor cursor)
/* --------------------------------------------------------------------------
External (RIF): set frame mouse pointer type.
}
-void
+static void
ns_clear_frame_area (struct frame *f, int x, int y, int width, int height)
/* --------------------------------------------------------------------------
External (RIF): Clear section of frame
NSTRACE (ns_after_update_window_line);
/* begin copy from other terms */
- xassert (w);
+ eassert (w);
if (!desired_row->mode_line_p && !w->pseudo_window_p)
desired_row->redraw_fringe_bitmaps_p = 1;
External (RIF); compute left/right overhang of whole string and set in s
-------------------------------------------------------------------------- */
{
- struct face *face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
- struct font *font = s->font; /*face->font; */
+ struct font *font = s->font;
if (s->char2b)
{
/* grow bimgs if needed */
if (nBimgs < max_used_fringe_bitmap)
{
- EmacsImage **newBimgs
- = xmalloc (max_used_fringe_bitmap * sizeof (EmacsImage *));
- memset (newBimgs, 0, max_used_fringe_bitmap * sizeof (EmacsImage *));
-
- if (nBimgs)
- {
- memcpy (newBimgs, bimgs, nBimgs * sizeof (EmacsImage *));
- xfree (bimgs);
- }
-
- bimgs = newBimgs;
+ bimgs = xrealloc (bimgs, max_used_fringe_bitmap * sizeof *bimgs);
+ memset (bimgs + nBimgs, 0,
+ (max_used_fringe_bitmap - nBimgs) * sizeof *bimgs);
nBimgs = max_used_fringe_bitmap;
}
if (p->which)
{
NSRect r = NSMakeRect (p->x+xAdjust, p->y, p->wd, p->h);
- NSPoint pt = r.origin;
EmacsImage *img = bimgs[p->which - 1];
if (!img)
to erase the whole background. */
[ns_lookup_indexed_color(face->background, f) set];
NSRectFill (r);
- pt.y += p->h;
[img setXBMColor: ns_lookup_indexed_color(face->foreground, f)];
- [img compositeToPoint: pt operation: NSCompositeSourceOver];
+ [img drawInRect: r
+ fromRect: NSZeroRect
+ operation: NSCompositeSourceOver
+ fraction: 1.0
+ respectFlipped: YES
+ hints: nil];
}
ns_unfocus (f);
}
-void
+static void
ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
int x, int y, int cursor_type, int cursor_width,
int on_p, int active_p)
return n;
}
+/* --------------------------------------------------------------------
+ Draw a wavy line under glyph string s. The wave fills wave_height
+ pixels from y.
+
+ x wave_length = 3
+ --
+ y * * * * *
+ |* * * * * * * * *
+ wave_height = 3 | * * * *
+ --------------------------------------------------------------------- */
+
+static void
+ns_draw_underwave (struct glyph_string *s, CGFloat width, CGFloat x)
+{
+ int wave_height = 3, wave_length = 3;
+ int y, dx, dy, odd, xmax;
+ NSPoint a, b;
+ NSRect waveClip;
+
+ dx = wave_length;
+ dy = wave_height - 1;
+ y = s->ybase + 1;
+ xmax = x + width;
+
+ /* Find and set clipping rectangle */
+ waveClip = NSMakeRect (x, y, width, wave_height);
+ [[NSGraphicsContext currentContext] saveGraphicsState];
+ NSRectClip (waveClip);
+
+ /* Draw the waves */
+ a.x = x - ((int)(x) % dx);
+ b.x = a.x + dx;
+ odd = (int)(a.x/dx) % 2;
+ a.y = b.y = y;
+
+ if (odd)
+ a.y += dy;
+ else
+ b.y += dy;
+
+ while (a.x <= xmax)
+ {
+ [NSBezierPath strokeLineFromPoint:a toPoint:b];
+ a.x = b.x, a.y = b.y;
+ b.x += dx, b.y = y + odd*dy;
+ odd = !odd;
+ }
+
+ /* Restore previous clipping rectangle(s) */
+ [[NSGraphicsContext currentContext] restoreGraphicsState];
+}
+
+
+
void
ns_draw_text_decoration (struct glyph_string *s, struct face *face,
NSColor *defaultCol, CGFloat width, CGFloat x)
/* Do underline. */
if (face->underline_p)
{
- NSRect r;
- unsigned long thickness, position;
-
- /* If the prev was underlined, match its appearance. */
- if (s->prev && s->prev->face->underline_p
- && s->prev->underline_thickness > 0)
+ if (s->face->underline_type == FACE_UNDER_WAVE)
{
- thickness = s->prev->underline_thickness;
- position = s->prev->underline_position;
+ if (face->underline_defaulted_p)
+ [defaultCol set];
+ else
+ [ns_lookup_indexed_color (face->underline_color, s->f) set];
+
+ ns_draw_underwave (s, width, x);
}
- else
+ else if (s->face->underline_type == FACE_UNDER_LINE)
{
- struct font *font;
- unsigned long descent;
-
- font=s->font;
- descent = s->y + s->height - s->ybase;
-
- /* Use underline thickness of font, defaulting to 1. */
- thickness = (font && font->underline_thickness > 0)
- ? font->underline_thickness : 1;
-
- /* Determine the offset of underlining from the baseline. */
- if (x_underline_at_descent_line)
- position = descent - thickness;
- else if (x_use_underline_position_properties
- && font && font->underline_position >= 0)
- position = font->underline_position;
- else if (font)
- position = lround (font->descent / 2);
- else
- position = underline_minimum_offset;
- position = max (position, underline_minimum_offset);
+ NSRect r;
+ unsigned long thickness, position;
- /* Ensure underlining is not cropped. */
- if (descent <= position)
+ /* If the prev was underlined, match its appearance. */
+ if (s->prev && s->prev->face->underline_p
+ && s->prev->underline_thickness > 0)
{
- position = descent - 1;
- thickness = 1;
+ thickness = s->prev->underline_thickness;
+ position = s->prev->underline_position;
}
- else if (descent < position + thickness)
- thickness = 1;
- }
+ else
+ {
+ struct font *font;
+ unsigned long descent;
+
+ font=s->font;
+ descent = s->y + s->height - s->ybase;
+
+ /* Use underline thickness of font, defaulting to 1. */
+ thickness = (font && font->underline_thickness > 0)
+ ? font->underline_thickness : 1;
+
+ /* Determine the offset of underlining from the baseline. */
+ if (x_underline_at_descent_line)
+ position = descent - thickness;
+ else if (x_use_underline_position_properties
+ && font && font->underline_position >= 0)
+ position = font->underline_position;
+ else if (font)
+ position = lround (font->descent / 2);
+ else
+ position = underline_minimum_offset;
- s->underline_thickness = thickness;
- s->underline_position = position;
+ position = max (position, underline_minimum_offset);
- r = NSMakeRect (x, s->ybase + position, width, thickness);
+ /* Ensure underlining is not cropped. */
+ if (descent <= position)
+ {
+ position = descent - 1;
+ thickness = 1;
+ }
+ else if (descent < position + thickness)
+ thickness = 1;
+ }
- if (face->underline_defaulted_p)
- [defaultCol set];
- else
- [ns_lookup_indexed_color (face->underline_color, s->f) set];
- NSRectFill (r);
- }
+ s->underline_thickness = thickness;
+ s->underline_position = position;
+ r = NSMakeRect (x, s->ybase + position, width, thickness);
+
+ if (face->underline_defaulted_p)
+ [defaultCol set];
+ else
+ [ns_lookup_indexed_color (face->underline_color, s->f) set];
+ NSRectFill (r);
+ }
+ }
/* Do overline. We follow other terms in using a thickness of 1
and ignoring overline_margin. */
if (face->overline_p)
/* Draw the image.. do we need to draw placeholder if img ==nil? */
if (img != nil)
- [img compositeToPoint: NSMakePoint (x, y + s->slice.height)
- operation: NSCompositeSourceOver];
+ [img drawInRect: br
+ fromRect: NSZeroRect
+ operation: NSCompositeSourceOver
+ fraction: 1.0
+ respectFlipped: YES
+ hints: nil];
if (s->hl == DRAW_CURSOR)
{
/* NSTRACE (ns_read_socket); */
+ if ([NSApp modalWindow] != nil)
+ return -1;
+
if (interrupt_input_blocked)
{
interrupt_input_pending = 1;
int
ns_select (int nfds, fd_set *readfds, fd_set *writefds,
- fd_set *exceptfds, struct timeval *timeout)
+ fd_set *exceptfds, EMACS_TIME *timeout, sigset_t *sigmask)
/* --------------------------------------------------------------------------
Replacement for select, checking for events
-------------------------------------------------------------------------- */
int result;
double time;
NSEvent *ev;
+ struct timespec select_timeout;
+
/* NSTRACE (ns_select); */
if (NSApp == nil || inNsSelect == 1 /* || ([NSApp isActive] == NO &&
[NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil
inMode:NSDefaultRunLoopMode dequeue:NO] == nil) */)
- return select (nfds, readfds, writefds, exceptfds, timeout);
+ return pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask);
/* Save file descriptor set, which gets overwritten in calls to select ()
Note, this is called from process.c, and only readfds is ever set */
select_nfds = 0;
/* Try an initial select for pending data on input files */
- select_timeout.tv_sec = select_timeout.tv_usec = 0;
- result = select (nfds, readfds, writefds, exceptfds, &select_timeout);
+ select_timeout.tv_sec = select_timeout.tv_nsec = 0;
+ result = pselect (nfds, readfds, writefds, exceptfds,
+ &select_timeout, sigmask);
if (result)
return result;
/* set a timeout and run the main AppKit event loop while continuing
to monitor the files */
- time = ((double) timeout->tv_sec) + ((double) timeout->tv_usec)/1000000.0;
+ time = EMACS_TIME_TO_DOUBLE (*timeout);
timed_entry = [[NSTimer scheduledTimerWithTimeInterval: time
target: NSApp
selector: @selector (timeout_handler:)
repeats: YES] /* for safe removal */
retain];
- /* set a periodic task to try the select () again */
+ /* set a periodic task to try the pselect () again */
fd_entry = [[NSTimer scheduledTimerWithTimeInterval: 0.1
target: NSApp
selector: @selector (fd_handler:)
}
else
{
- /* Received back from select () in fd_handler; copy the results */
+ /* Received back from pselect () in fd_handler; copy the results */
if (readfds)
memcpy (readfds, &select_readfds, sizeof (fd_set));
return t;
BOOL barOnVeryLeft, barOnVeryRight;
int top, left, height, width, sb_width, sb_left;
EmacsScroller *bar;
-static int count = 0;
/* optimization; display engine sends WAY too many of these.. */
if (!NILP (window->vertical_scroll_bar))
{
bar = XNS_SCROLL_BAR (window->vertical_scroll_bar);
[bar removeFromSuperview];
- window->vertical_scroll_bar = Qnil;
+ WSET (window, vertical_scroll_bar, Qnil);
}
ns_clear_frame_area (f, sb_left, top, width, height);
UNBLOCK_INPUT;
{
ns_clear_frame_area (f, sb_left, top, width, height);
bar = [[EmacsScroller alloc] initFrame: r window: win];
- window->vertical_scroll_bar = make_save_value (bar, 0);
+ WSET (window, vertical_scroll_bar, make_save_value (bar, 0));
}
else
{
NSTRACE (ns_redeem_scroll_bar);
if (!NILP (window->vertical_scroll_bar))
{
- bar =XNS_SCROLL_BAR (window->vertical_scroll_bar);
+ bar = XNS_SCROLL_BAR (window->vertical_scroll_bar);
[bar reprieve];
}
}
Convert modifier name to lisp symbol
-------------------------------------------------------------------------- */
{
- if (!strncmp (SDATA (SYMBOL_NAME (Qmeta)), s, 10))
+ if (!strncmp (SSDATA (SYMBOL_NAME (Qmeta)), s, 10))
return Qmeta;
- else if (!strncmp (SDATA (SYMBOL_NAME (Qsuper)), s, 10))
+ else if (!strncmp (SSDATA (SYMBOL_NAME (Qsuper)), s, 10))
return Qsuper;
- else if (!strncmp (SDATA (SYMBOL_NAME (Qcontrol)), s, 10))
+ else if (!strncmp (SSDATA (SYMBOL_NAME (Qcontrol)), s, 10))
return Qcontrol;
- else if (!strncmp (SDATA (SYMBOL_NAME (Qalt)), s, 10))
+ else if (!strncmp (SSDATA (SYMBOL_NAME (Qalt)), s, 10))
return Qalt;
- else if (!strncmp (SDATA (SYMBOL_NAME (Qhyper)), s, 10))
+ else if (!strncmp (SSDATA (SYMBOL_NAME (Qhyper)), s, 10))
return Qhyper;
- else if (!strncmp (SDATA (SYMBOL_NAME (Qnone)), s, 10))
+ else if (!strncmp (SSDATA (SYMBOL_NAME (Qnone)), s, 10))
return Qnone;
else
return Qnil;
}
-static Lisp_Object ns_mod_to_lisp (int m)
-/* --------------------------------------------------------------------------
- Convert modifier code (see lisp.h) to lisp symbol
- -------------------------------------------------------------------------- */
-{
- if (m == CHAR_META)
- return Qmeta;
- else if (m == CHAR_SUPER)
- return Qsuper;
- else if (m == CHAR_CTL)
- return Qcontrol;
- else if (m == CHAR_ALT)
- return Qalt;
- else if (m == CHAR_HYPER)
- return Qhyper;
- else /* if (m == 0) */
- return Qnone;
-}
-
-
static void
ns_default (const char *parameter, Lisp_Object *result,
Lisp_Object yesval, Lisp_Object noval,
{
double f;
char *pos;
- if (strcasecmp (value, "YES") == 0)
+ if (c_strcasecmp (value, "YES") == 0)
*result = yesval;
- else if (strcasecmp (value, "NO") == 0)
+ else if (c_strcasecmp (value, "NO") == 0)
*result = noval;
else if (is_float && (f = strtod (value, &pos), pos != value))
*result = make_float (f);
}
-void
+static void
ns_initialize_display_info (struct ns_display_info *dpyinfo)
/* --------------------------------------------------------------------------
Initialize global info and storage for display.
NSColorSpaceFromDepth (depth)];
dpyinfo->n_planes = NSBitsPerPixelFromDepth (depth);
dpyinfo->image_cache = make_image_cache ();
- dpyinfo->color_table
- = (struct ns_color_table *)xmalloc (sizeof (struct ns_color_table));
+ dpyinfo->color_table = xmalloc (sizeof *dpyinfo->color_table);
dpyinfo->color_table->colors = NULL;
dpyinfo->root_window = 42; /* a placeholder.. */
ns_delete_terminal (struct terminal *terminal)
{
struct ns_display_info *dpyinfo = terminal->display_info.ns;
- int i;
/* Protect against recursive calls. delete_frame in
delete_terminal calls us back when it deletes our last frame. */
ns_pending_service_names = [[NSMutableArray alloc] init];
ns_pending_service_args = [[NSMutableArray alloc] init];
- /* Start app and create the main menu, window, view.
+/* Start app and create the main menu, window, view.
Needs to be here because ns_initialize_display_info () uses AppKit classes.
The view will then ask the NSApp to stop and return to Emacs. */
[EmacsApp sharedApplication];
selector: @selector (logNotification:)
name: nil object: nil]; */
- dpyinfo = (struct ns_display_info *)xmalloc (sizeof (struct ns_display_info));
- memset (dpyinfo, 0, sizeof (struct ns_display_info));
+ dpyinfo = xzalloc (sizeof *dpyinfo);
ns_initialize_display_info (dpyinfo);
terminal = ns_create_terminal (dpyinfo);
- terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
+ terminal->kboard = xmalloc (sizeof *terminal->kboard);
init_kboard (terminal->kboard);
KVAR (terminal->kboard, Vwindow_system) = Qns;
terminal->kboard->next_kboard = all_kboards;
ns_display_name_list);
dpyinfo->name_list_element = XCAR (ns_display_name_list);
- /* Set the name of the terminal. */
- terminal->name = (char *) xmalloc (SBYTES (display_name) + 1);
- strncpy (terminal->name, SDATA (display_name), SBYTES (display_name));
- terminal->name[SBYTES (display_name)] = 0;
+ terminal->name = xstrdup (SSDATA (display_name));
UNBLOCK_INPUT;
if ( cl == nil )
{
Lisp_Object color_file, color_map, color;
- int r,g,b;
unsigned long c;
char *name;
for ( ; CONSP (color_map); color_map = XCDR (color_map))
{
color = XCAR (color_map);
- name = SDATA (XCAR (color));
+ name = SSDATA (XCAR (color));
c = XINT (XCDR (color));
[cl setColor:
[NSColor colorWithCalibratedRed: RED_FROM_ULONG (c) / 255.0
}
{
- char c[128];
#ifdef NS_IMPL_GNUSTEP
- strncpy (c, gnustep_base_version, sizeof (c));
+ Vwindow_system_version = build_string (gnustep_base_version);
#else
/*PSnextrelease (128, c); */
- snprintf (c, sizeof (c), "%g", NSAppKitVersionNumber);
+ char c[DBL_BUFSIZE_BOUND];
+ int len = dtoastr (c, sizeof c, 0, 0, NSAppKitVersionNumber);
+ Vwindow_system_version = make_unibyte_string (c, len);
#endif
- Vwindow_system_version = build_string (c);
}
delete_keyboard_wait_descriptor (0);
#endif /* MAC OS X menu setup */
[NSApp run];
-
+ ns_do_open_file = YES;
return dpyinfo;
}
/* code not reached in emacs.c after this is called by shut_down_emacs: */
if (STRINGP (Vauto_save_list_file_name))
- unlink (SDATA (Vauto_save_list_file_name));
+ unlink (SSDATA (Vauto_save_list_file_name));
if (sig == 0 || sig == SIGTERM)
{
return NSTerminateNow;
ret = NSRunAlertPanel(ns_app_name,
- [NSString stringWithUTF8String:"Exit requested. Would you like to Save Buffers and Exit, or Cancel the request?"],
+ @"Exit requested. Would you like to Save Buffers and Exit, or Cancel the request?",
@"Save Buffers and Exit", @"Cancel", nil);
if (ret == NSAlertDefaultReturn)
/* Notification from the Workspace to open a file */
- (BOOL)application: sender openFile: (NSString *)file
{
- [ns_pending_files addObject: file];
+ if (ns_do_open_file)
+ [ns_pending_files addObject: file];
return YES;
}
/* Open a file as a temporary file */
- (BOOL)application: sender openTempFile: (NSString *)file
{
- [ns_pending_files addObject: file];
+ if (ns_do_open_file)
+ [ns_pending_files addObject: file];
return YES;
}
/* Notification from the Workspace to open a file noninteractively (?) */
- (BOOL)application: sender openFileWithoutUI: (NSString *)file
{
- [ns_pending_files addObject: file];
+ if (ns_do_open_file)
+ [ns_pending_files addObject: file];
return YES;
}
/* Notification from the Workspace to open multiple files */
- (void)application: sender openFiles: (NSArray *)fileList
{
- NSEnumerator *files = [fileList objectEnumerator];
- NSString *file;
- while ((file = [files nextObject]) != nil)
- [ns_pending_files addObject: file];
-
+ /* Don't open files from the command line, Cocoa parses the command line
+ wrong anyway, --option value tries to open value if --option is the last
+ option. */
+ if (ns_do_open_file)
+ {
+ NSEnumerator *files = [fileList objectEnumerator];
+ NSString *file;
+ while ((file = [files nextObject]) != nil)
+ [ns_pending_files addObject: file];
+ }
+
[self replyToOpenOrPrint: NSApplicationDelegateReplySuccess];
}
-------------------------------------------------------------------------- */
{
int result;
+ struct timespec select_timeout;
/* NSTRACE (fd_handler); */
if (select_nfds == 0)
memcpy (&t_readfds, &select_readfds, sizeof (fd_set));
- select_timeout.tv_sec = select_timeout.tv_usec = 0;
- result = select (select_nfds, &t_readfds, (SELECT_TYPE *)0, (SELECT_TYPE *)0,
- &select_timeout);
+ select_timeout.tv_sec = select_timeout.tv_nsec = 0;
+ result = pselect (select_nfds, &t_readfds, NULL, NULL, &select_timeout, NULL);
if (result)
{
memcpy (&select_readfds, &t_readfds, sizeof (fd_set));
{
[ns_pending_service_names addObject: userData];
[ns_pending_service_args addObject: [NSString stringWithUTF8String:
- SDATA (ns_string_from_pasteboard (pboard))]];
+ SSDATA (ns_string_from_pasteboard (pboard))]];
}
if (!emacs_event)
return;
- if (newFont = [sender convertFont:
- ((struct nsfont_info *)face->font)->nsfont])
+ if ((newFont = [sender convertFont:
+ ((struct nsfont_info *)face->font)->nsfont]))
{
SET_FRAME_GARBAGED (emacsframe); /* now needed as of 2008/10 */
if (!processingCompose)
{
+ /* When using screen sharing, no left or right information is sent,
+ so use Left key in those cases. */
+ int is_left_key, is_right_key;
+
code = ([[theEvent charactersIgnoringModifiers] length] == 0) ?
0 : [[theEvent charactersIgnoringModifiers] characterAtIndex: 0];
+
/* (Carbon way: [theEvent keyCode]) */
/* is it a "function key"? */
if (flags & NSShiftKeyMask)
emacs_event->modifiers |= shift_modifier;
- if ((flags & NSRightCommandKeyMask) == NSRightCommandKeyMask)
+ is_right_key = (flags & NSRightCommandKeyMask) == NSRightCommandKeyMask;
+ is_left_key = (flags & NSLeftCommandKeyMask) == NSLeftCommandKeyMask
+ || (! is_right_key && (flags & NSCommandKeyMask) == NSCommandKeyMask);
+
+ if (is_right_key)
emacs_event->modifiers |= parse_solitary_modifier
(EQ (ns_right_command_modifier, Qleft)
? ns_command_modifier
: ns_right_command_modifier);
- if ((flags & NSLeftCommandKeyMask) == NSLeftCommandKeyMask)
+ if (is_left_key)
{
emacs_event->modifiers |= parse_solitary_modifier
(ns_command_modifier);
}
}
- if ((flags & NSRightControlKeyMask) == NSRightControlKeyMask)
+ is_right_key = (flags & NSRightControlKeyMask) == NSRightControlKeyMask;
+ is_left_key = (flags & NSLeftControlKeyMask) == NSLeftControlKeyMask
+ || (! is_right_key && (flags & NSControlKeyMask) == NSControlKeyMask);
+
+ if (is_right_key)
emacs_event->modifiers |= parse_solitary_modifier
(EQ (ns_right_control_modifier, Qleft)
? ns_control_modifier
: ns_right_control_modifier);
- if ((flags & NSLeftControlKeyMask) == NSLeftControlKeyMask)
+ if (is_left_key)
emacs_event->modifiers |= parse_solitary_modifier
(ns_control_modifier);
left_is_none = NILP (ns_alternate_modifier)
|| EQ (ns_alternate_modifier, Qnone);
- if ((flags & NSRightAlternateKeyMask) == NSRightAlternateKeyMask)
+ is_right_key = (flags & NSRightAlternateKeyMask)
+ == NSRightAlternateKeyMask;
+ is_left_key = (flags & NSLeftAlternateKeyMask) == NSLeftAlternateKeyMask
+ || (! is_right_key
+ && (flags & NSAlternateKeyMask) == NSAlternateKeyMask);
+
+ if (is_right_key)
{
if ((NILP (ns_right_alternate_modifier)
|| EQ (ns_right_alternate_modifier, Qnone)
: ns_right_alternate_modifier);
}
- if ((flags & NSLeftAlternateKeyMask) == NSLeftAlternateKeyMask) /* default = meta */
+ if (is_left_key) /* default = meta */
{
if (left_is_none && !fnKeysym)
{ /* accept pre-interp alt comb */
}
-- (long)conversationIdentifier
+- (NSInteger)conversationIdentifier
{
- return (long)self;
+ return (NSInteger)self;
}
- (void)mouseDown: (NSEvent *)theEvent
{
NSPoint p = [self convertPoint: [theEvent locationInWindow] fromView: nil];
- Lisp_Object window;
NSTRACE (mouseDown);
char *pos = strstr (t, " — ");
if (pos)
*pos = '\0';
- old_title = (char *) xmalloc (strlen (t) + 1);
- strcpy (old_title, t);
+ old_title = xstrdup (t);
}
size_title = xmalloc (strlen (old_title) + 40);
esprintf (size_title, "%s — (%d x %d)", old_title, cols, rows);
- (void)windowDidResize: (NSNotification *)notification
{
+#ifdef NS_IMPL_GNUSTEP
NSWindow *theWindow = [notification object];
-#ifdef NS_IMPL_GNUSTEP
/* in GNUstep, at least currently, it's possible to get a didResize
without getting a willResize.. therefore we need to act as if we got
the willResize now */
Lisp_Object tem;
NSWindow *win;
NSButton *toggleButton;
- int vbextra = NS_SCROLL_BAR_WIDTH (f);
NSSize sz;
NSColor *col;
NSString *name;
tem = f->name;
name = [NSString stringWithUTF8String:
- NILP (tem) ? (unsigned char *)"Emacs" : SDATA (tem)];
+ NILP (tem) ? "Emacs" : SSDATA (tem)];
[win setTitle: name];
/* toolbar support */
tem = f->icon_name;
if (!NILP (tem))
[win setMiniwindowTitle:
- [NSString stringWithUTF8String: SDATA (tem)]];
+ [NSString stringWithUTF8String: SSDATA (tem)]];
{
NSScreen *screen = [win screen];
- (void)mouseEntered: (NSEvent *)theEvent
{
- NSPoint p = [self convertPoint: [theEvent locationInWindow] fromView: nil];
- struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe);
NSTRACE (mouseEntered);
-
last_mouse_movement_time = EV_TIMESTAMP (theEvent);
}
- (void)mouseExited: (NSEvent *)theEvent
{
- NSPoint p = [self convertPoint: [theEvent locationInWindow] fromView: nil];
- NSRect r;
Mouse_HLInfo *hlinfo = emacsframe ? MOUSE_HL_INFO (emacsframe) : NULL;
NSTRACE (mouseExited);
NSTRACE (menuDown);
if (context_menu_value == -1)
context_menu_value = [sender tag];
- else
- find_and_call_menu_selection (emacsframe, emacsframe->menu_bar_items_used,
- emacsframe->menu_bar_vector,
- (void *)[sender tag]);
+ else
+ {
+ NSInteger tag = [sender tag];
+ find_and_call_menu_selection (emacsframe, emacsframe->menu_bar_items_used,
+ emacsframe->menu_bar_vector,
+ (void *)tag);
+ }
+
ns_send_appdefined (-1);
return self;
}
emacs_event->kind = TOOL_BAR_EVENT;
/* XSETINT (emacs_event->code, 0); */
emacs_event->arg = AREF (emacsframe->tool_bar_items,
- idx + TOOL_BAR_ITEM_KEY);
+ idx + TOOL_BAR_ITEM_KEY);
emacs_event->modifiers = EV_MODIFIERS (theEvent);
EV_TRAILER (theEvent);
return self;
@implementation EmacsWindow
+#ifdef NS_IMPL_COCOA
+- (id)accessibilityAttributeValue:(NSString *)attribute
+{
+ Lisp_Object str = Qnil;
+ struct frame *f = SELECTED_FRAME ();
+ struct buffer *curbuf = XBUFFER (XWINDOW (f->selected_window)->buffer);
+
+ if ([attribute isEqualToString:NSAccessibilityRoleAttribute])
+ return NSAccessibilityTextFieldRole;
+
+ if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute]
+ && curbuf && ! NILP (BVAR (curbuf, mark_active)))
+ {
+ str = ns_get_local_selection (QPRIMARY, QUTF8_STRING);
+ }
+ else if (curbuf && [attribute isEqualToString:NSAccessibilityValueAttribute])
+ {
+ if (! NILP (BVAR (curbuf, mark_active)))
+ str = ns_get_local_selection (QPRIMARY, QUTF8_STRING);
+
+ if (NILP (str))
+ {
+ ptrdiff_t start_byte = BUF_BEGV_BYTE (curbuf);
+ ptrdiff_t byte_range = BUF_ZV_BYTE (curbuf) - start_byte;
+ ptrdiff_t range = BUF_ZV (curbuf) - BUF_BEGV (curbuf);
+
+ if (! NILP (BVAR (curbuf, enable_multibyte_characters)))
+ str = make_uninit_multibyte_string (range, byte_range);
+ else
+ str = make_uninit_string (range);
+ /* To check: This returns emacs-utf-8, which is a superset of utf-8.
+ Is this a problem? */
+ memcpy (SDATA (str), BYTE_POS_ADDR (start_byte), byte_range);
+ }
+ }
+
+
+ if (! NILP (str))
+ {
+ if (CONSP (str) && SYMBOLP (XCAR (str)))
+ {
+ str = XCDR (str);
+ if (CONSP (str) && NILP (XCDR (str)))
+ str = XCAR (str);
+ }
+ if (STRINGP (str))
+ {
+ const char *utfStr = SSDATA (str);
+ NSString *nsStr = [NSString stringWithUTF8String: utfStr];
+ return nsStr;
+ }
+ }
+
+ return [super accessibilityAttributeValue:attribute];
+}
+#endif /* NS_IMPL_COCOA */
+
/* If we have multiple monitors, one above the other, we don't want to
restrict the height to just one monitor. So we override this. */
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen
{
- /* When making the frame visible for the first time, we want to
- constrain. Other times not. */
+ /* When making the frame visible for the first time or if there is just
+ one screen, we want to constrain. Other times not. */
+ NSUInteger nr_screens = [[NSScreen screens] count];
struct frame *f = ((EmacsView *)[self delegate])->emacsframe;
NSTRACE (constrainFrameRect);
+ if (nr_screens == 1)
+ return [super constrainFrameRect:frameRect toScreen:screen];
+
if (f->output_data.ns->dont_constrain
|| ns_menu_bar_should_be_hidden ())
return frameRect;
{
NSTRACE (EmacsScroller_dealloc);
if (!NILP (win))
- XWINDOW (win)->vertical_scroll_bar = Qnil;
+ WSET (XWINDOW (win), vertical_scroll_bar, Qnil);
[super dealloc];
}