X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/d180bde8e49f2475adbbd987d3f98dde20c9b18e..95c216526e3700d46319d8fb47844a5e07662bbf:/src/nsterm.m diff --git a/src/nsterm.m b/src/nsterm.m index ce8d9b2106..733c05ae53 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -1,7 +1,7 @@ /* NeXT/Open/GNUstep / MacOSX communication module. -Copyright (C) 1989, 1993-1994, 2005-2006, 2008-2013 Free Software -Foundation, Inc. +Copyright (C) 1989, 1993-1994, 2005-2006, 2008-2013 + Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -173,6 +173,7 @@ Lisp_Object Qalt, Qcontrol, Qhyper, Qmeta, Qsuper; extern Lisp_Object Qcursor_color, Qcursor_type, Qns, Qleft; static Lisp_Object QUTF8_STRING; +static Lisp_Object Qcocoa, Qgnustep; /* On OS X picks up the default NSGlobalDomain AppleAntiAliasingThreshold, the maximum font size to NOT antialias. On GNUstep there is currently @@ -184,7 +185,6 @@ NSString *ns_app_name = @"Emacs"; /* default changed later */ /* Display variables */ struct ns_display_info *x_display_list; /* Chain of existing displays */ -Lisp_Object ns_display_name_list; long context_menu_value = 0; /* display update */ @@ -445,8 +445,8 @@ ns_exec_path (void) 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. */ + the filenames of the site-lisp and lisp directories. + Ie, site-lisp:lisp. Otherwise, return nil. */ { NSBundle *bundle = [NSBundle mainBundle]; NSString *resourceDir = [bundle resourcePath]; @@ -456,7 +456,7 @@ ns_load_path (void) BOOL isDir; NSArray *paths = [resourceDir stringsByAppendingPaths: [NSArray arrayWithObjects: - @"site-lisp", @"lisp", @"leim", nil]]; + @"site-lisp", @"lisp", nil]]; NSEnumerator *pathEnum = [paths objectEnumerator]; resourcePaths = @""; @@ -771,7 +771,12 @@ ns_update_window_end (struct window *w, bool cursor_on_p, w->output_cursor.x, w->output_cursor.y); if (draw_window_fringes (w, 1)) - x_draw_vertical_border (w); + { + if (WINDOW_RIGHT_DIVIDER_WIDTH (w)) + x_draw_right_divider (w); + else + x_draw_vertical_border (w); + } unblock_input (); } @@ -1150,9 +1155,7 @@ x_free_frame_resources (struct frame *f) block_input (); free_frame_menubar (f); - - if (FRAME_FACE_CACHE (f)) - free_frame_faces (f); + free_frame_faces (f); if (f == dpyinfo->x_focus_frame) dpyinfo->x_focus_frame = 0; @@ -1235,7 +1238,11 @@ x_set_offset (struct frame *f, int xoff, int yoff, int change_grav) void -x_set_window_size (struct frame *f, int change_grav, int cols, int rows) +x_set_window_size (struct frame *f, + int change_grav, + int width, + int height, + bool pixelwise) /* -------------------------------------------------------------------------- Adjust window pixel size based on given character grid size Impl is a bit more complex than other terms, need to do some @@ -1247,23 +1254,36 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows) NSRect wr = [window frame]; int tb = FRAME_EXTERNAL_TOOL_BAR (f); int pixelwidth, pixelheight; + int rows, cols; NSTRACE (x_set_window_size); if (view == nil) return; -/*fprintf (stderr, "\tsetWindowSize: %d x %d, font size %d x %d\n", cols, rows, FRAME_COLUMN_WIDTH (f), FRAME_LINE_HEIGHT (f)); */ +/*fprintf (stderr, "\tsetWindowSize: %d x %d, pixelwise %d, font size %d x %d\n", width, height, pixelwise, FRAME_COLUMN_WIDTH (f), FRAME_LINE_HEIGHT (f));*/ block_input (); - check_frame_size (f, &rows, &cols); + check_frame_size (f, &width, &height, pixelwise); f->scroll_bar_actual_width = NS_SCROLL_BAR_WIDTH (f); compute_fringe_widths (f, 0); - pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols); - pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, rows); + if (pixelwise) + { + pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width); + pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height); + cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixelwidth); + rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixelheight); + } + else + { + pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width); + pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height); + cols = width; + rows = height; + } /* If we have a toolbar, take its height into account. */ if (tb && ! [view isFullscreen]) @@ -1298,8 +1318,6 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows) [view setRows: rows andColumns: cols]; [window setFrame: wr display: YES]; -/*fprintf (stderr, "\tx_set_window_size %d, %d\t%d, %d\n", cols, rows, pixelwidth, pixelheight); */ - /* This is a trick to compensate for Emacs' managing the scrollbar area as a fixed number of standard character columns. Instead of leaving blank space for the extra, we chopped it off above. Now for @@ -1316,9 +1334,7 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows) [view setBoundsOrigin: origin]; } - change_frame_size (f, rows, cols, 0, 1, 0); /* pretend, delay, safe */ - FRAME_PIXEL_WIDTH (f) = pixelwidth; - FRAME_PIXEL_HEIGHT (f) = pixelheight; + change_frame_size (f, width, height, 0, 1, 0, pixelwise); /* SET_FRAME_GARBAGED (f); // this short-circuits expose call in drawRect */ mark_window_cursors_off (XWINDOW (f->root_window)); @@ -1385,7 +1401,7 @@ ns_index_color (NSColor *color, struct frame *f) color_table->empty_indices = [[NSMutableSet alloc] init]; } - /* do we already have this color ? */ + /* Do we already have this color? */ for (i = 1; i < color_table->avail; i++) if (color_table->colors[i] && [color_table->colors[i] isEqual: color]) return i; @@ -1461,15 +1477,16 @@ ns_get_color (const char *name, NSColor **col) /*fprintf (stderr, "ns_get_color: '%s'\n", name); */ block_input (); -#ifdef NS_IMPL_COCOA if ([nsname isEqualToString: @"ns_selection_bg_color"]) { +#ifdef NS_IMPL_COCOA NSString *defname = [[NSUserDefaults standardUserDefaults] stringForKey: @"AppleHighlightColor"]; - if (defname != nil) nsname = defname; - else if ((new = [NSColor selectedTextBackgroundColor]) != nil) + else +#endif + if ((new = [NSColor selectedTextBackgroundColor]) != nil) { *col = [new colorUsingColorSpaceName: NSCalibratedRGBColorSpace]; unblock_input (); @@ -1495,7 +1512,6 @@ ns_get_color (const char *name, NSColor **col) nsname = NS_SELECTION_FG_COLOR_DEFAULT; name = [nsname UTF8String]; } -#endif // NS_IMPL_COCOA /* First, check for some sort of numeric specification. */ hex[0] = '\0'; @@ -2504,6 +2520,28 @@ ns_draw_vertical_window_border (struct window *w, int x, int y0, int y1) } +static void +ns_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1) +/* -------------------------------------------------------------------------- + External (RIF): Draw a window divider. + -------------------------------------------------------------------------- */ +{ + struct frame *f = XFRAME (WINDOW_FRAME (w)); + struct face *face; + NSRect r = NSMakeRect (x0, y0, x1-x0, y1-y0); + + NSTRACE (ns_draw_window_divider); + + face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID); + if (face) + [ns_lookup_indexed_color(face->foreground, f) set]; + + ns_focus (f, &r, 1); + NSRectFill(r); + ns_unfocus (f); +} + + void show_hourglass (struct atimer *timer) { @@ -3975,7 +4013,6 @@ ns_initialize_display_info (struct ns_display_info *dpyinfo) && ![NSCalibratedWhiteColorSpace isEqualToString: NSColorSpaceFromDepth (depth)]; dpyinfo->n_planes = NSBitsPerPixelFromDepth (depth); - dpyinfo->image_cache = make_image_cache (); dpyinfo->color_table = xmalloc (sizeof *dpyinfo->color_table); dpyinfo->color_table->colors = NULL; dpyinfo->root_window = 42; /* a placeholder.. */ @@ -4018,6 +4055,7 @@ static struct redisplay_interface ns_redisplay_interface = ns_clear_frame_area, ns_draw_window_cursor, ns_draw_vertical_window_border, + ns_draw_window_divider, ns_shift_glyphs_for_insert }; @@ -4091,12 +4129,6 @@ ns_create_terminal (struct ns_display_info *dpyinfo) terminal->delete_frame_hook = x_destroy_window; terminal->delete_terminal_hook = ns_delete_terminal; - terminal->scroll_region_ok = 1; - terminal->char_ins_del_ok = 1; - terminal->line_ins_del_ok = 1; - terminal->fast_clear_end_of_line = 1; - terminal->memory_below_frame = 0; - return terminal; } @@ -4169,11 +4201,7 @@ ns_term_init (Lisp_Object display_name) ns_initialize_display_info (dpyinfo); terminal = ns_create_terminal (dpyinfo); - terminal->kboard = xmalloc (sizeof *terminal->kboard); - init_kboard (terminal->kboard); - kset_window_system (terminal->kboard, Qns); - terminal->kboard->next_kboard = all_kboards; - all_kboards = terminal->kboard; + terminal->kboard = allocate_kboard (Qns); /* Don't let the initial kboard remain current longer than necessary. That would cause problems if a file loaded on startup tries to prompt in the mini-buffer. */ @@ -4184,10 +4212,7 @@ ns_term_init (Lisp_Object display_name) dpyinfo->next = x_display_list; x_display_list = dpyinfo; - /* Put it on ns_display_name_list */ - ns_display_name_list = Fcons (Fcons (display_name, Qnil), - ns_display_name_list); - dpyinfo->name_list_element = XCAR (ns_display_name_list); + dpyinfo->name_list_element = Fcons (display_name, Qnil); terminal->name = xstrdup (SSDATA (display_name)); @@ -4381,6 +4406,56 @@ ns_term_shutdown (int sig) @implementation EmacsApp +- (id)init +{ + if (self = [super init]) + { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9 + self->isFirst = YES; +#endif +#ifdef NS_IMPL_GNUSTEP + self->applicationDidFinishLaunchingCalled = NO; +#endif + } + + return self; +} + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9 +- (void)run +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + if (isFirst) [self finishLaunching]; + isFirst = NO; + + shouldKeepRunning = YES; + do + { + [pool release]; + pool = [[NSAutoreleasePool alloc] init]; + + NSEvent *event = + [self nextEventMatchingMask:NSAnyEventMask + untilDate:[NSDate distantFuture] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + [self sendEvent:event]; + [self updateWindows]; + } while (shouldKeepRunning); + + [pool release]; +} + +- (void)stop: (id)sender +{ + shouldKeepRunning = NO; + // Stop possible dialog also. Noop if no dialog present. + // The file dialog still leaks 7k - 10k on 10.9 though. + [super stop:sender]; +} +#endif + - (void)logNotification: (NSNotification *)notification { const char *name = [[notification name] UTF8String]; @@ -4533,6 +4608,9 @@ ns_term_shutdown (int sig) -------------------------------------------------------------------------- */ { NSTRACE (applicationDidFinishLaunching); +#ifdef NS_IMPL_GNUSTEP + ((EmacsApp *)self)->applicationDidFinishLaunchingCalled = YES; +#endif [NSApp setServicesProvider: NSApp]; ns_send_appdefined (-2); } @@ -4660,6 +4738,10 @@ not_in_argv (NSString *arg) { NSTRACE (applicationDidBecomeActive); +#ifdef NS_IMPL_GNUSTEP + if (! applicationDidFinishLaunchingCalled) + [self applicationDidFinishLaunching:notification]; +#endif //ns_app_active=YES; ns_update_auto_hide_menu_bar (); @@ -5591,44 +5673,44 @@ not_in_argv (NSString *arg) NSWindow *window = [self window]; NSRect wr = [window frame]; int extra = 0; - int gsextra = 0; -#ifdef NS_IMPL_GNUSTEP - gsextra = 3; -#endif - int oldc = cols, oldr = rows; int oldw = FRAME_PIXEL_WIDTH (emacsframe), oldh = FRAME_PIXEL_HEIGHT (emacsframe); int neww, newh; - cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, wr.size.width + gsextra); - - if (cols < MINWIDTH) - cols = MINWIDTH; - if (! [self isFullscreen]) { +#ifdef NS_IMPL_GNUSTEP + // GNUStep does not always update the tool bar height. Force it. + if (toolbar) update_frame_tool_bar (emacsframe); +#endif + extra = FRAME_NS_TITLEBAR_HEIGHT (emacsframe) - + FRAME_TOOLBAR_HEIGHT (emacsframe) - gsextra; + + FRAME_TOOLBAR_HEIGHT (emacsframe); } - rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (emacsframe, wr.size.height - extra); + neww = (int)wr.size.width - emacsframe->border_width; + newh = (int)wr.size.height - extra; + + cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, neww); + rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (emacsframe, newh); + + if (cols < MINWIDTH) + cols = MINWIDTH; if (rows < MINHEIGHT) rows = MINHEIGHT; - neww = (int)wr.size.width - emacsframe->border_width; - newh = (int)wr.size.height - extra; - if (oldr != rows || oldc != cols || neww != oldw || newh != oldh) { NSView *view = FRAME_NS_VIEW (emacsframe); NSWindow *win = [view window]; NSSize sz = [win resizeIncrements]; - FRAME_PIXEL_WIDTH (emacsframe) = neww; - FRAME_PIXEL_HEIGHT (emacsframe) = newh; - change_frame_size (emacsframe, rows, cols, 0, delay, 0); + change_frame_size (emacsframe, + FRAME_PIXEL_TO_TEXT_WIDTH (emacsframe, neww), + FRAME_PIXEL_TO_TEXT_HEIGHT (emacsframe, newh), + 0, delay, 0, 1); SET_FRAME_GARBAGED (emacsframe); cancel_mouse_face (emacsframe); @@ -5650,10 +5732,6 @@ not_in_argv (NSString *arg) /* normalize frame to gridded text size */ { int extra = 0; - int gsextra = 0; -#ifdef NS_IMPL_GNUSTEP - gsextra = 3; -#endif NSTRACE (windowWillResize); /*fprintf (stderr,"Window will resize: %.0f x %.0f\n",frameSize.width,frameSize.height); */ @@ -5671,8 +5749,13 @@ not_in_argv (NSString *arg) if (fs_state == FULLSCREEN_NONE) maximized_width = maximized_height = -1; - cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, - frameSize.width + gsextra); + if (! [self isFullscreen]) + { + extra = FRAME_NS_TITLEBAR_HEIGHT (emacsframe) + + FRAME_TOOLBAR_HEIGHT (emacsframe); + } + + cols = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (emacsframe, frameSize.width); if (cols < MINWIDTH) cols = MINWIDTH; @@ -6063,7 +6146,7 @@ if (cols > 0 && rows > 0) SET_FRAME_ICONIFIED (emacsframe, 0); SET_FRAME_VISIBLE (emacsframe, 1); - windows_or_buffers_changed++; + windows_or_buffers_changed = 63; if (emacs_event) { @@ -7268,6 +7351,7 @@ Lisp_Object x_new_font (struct frame *f, Lisp_Object font_object, int fontset) { struct font *font = XFONT_OBJECT (font_object); + EmacsView *view = FRAME_NS_VIEW (f); if (fontset < 0) fontset = fontset_from_font (font_object); @@ -7300,8 +7384,9 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset) } /* Now make the frame display the given font. */ - if (FRAME_NS_WINDOW (f) != 0) - x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f)); + if (FRAME_NS_WINDOW (f) != 0 && ! [view isFullscreen]) + x_set_window_size (f, 0, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), + FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 1); return font_object; } @@ -7471,9 +7556,6 @@ allowing it to be used at a lower level for accented character entry."); "Whether to confirm application quit using dialog."); ns_confirm_quit = Qnil; - staticpro (&ns_display_name_list); - ns_display_name_list = Qnil; - DEFVAR_LISP ("ns-auto-hide-menu-bar", ns_auto_hide_menu_bar, doc: /* Non-nil means that the menu bar is hidden, but appears when the mouse is near. Only works on OSX 10.6 or later. */); @@ -7519,11 +7601,17 @@ baseline level. The default value is nil. */); /* Tell Emacs about this window system. */ Fprovide (Qns, Qnil); + DEFSYM (Qcocoa, "cocoa"); + DEFSYM (Qgnustep, "gnustep"); + syms_of_nsfont (); #ifdef NS_IMPL_COCOA + Fprovide (Qcocoa, Qnil); #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 syms_of_macfont (); #endif +#else + Fprovide (Qgnustep, Qnil); #endif - + }