X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/b7a6f9f7919b7fc0871ae768b58f8e746aa7dd9f..18da0d8ad4e5036185acbad3238cbfe2aaf3ca66:/src/nsterm.m diff --git a/src/nsterm.m b/src/nsterm.m index fb1b0aa327..dc27fd09e3 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -60,6 +60,16 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu) #include "buffer.h" #include "font.h" +#ifdef NS_IMPL_GNUSTEP +#include "process.h" +#endif + +#ifdef NS_IMPL_COCOA +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +#include "macfont.h" +#endif +#endif + /* call tracing */ #if 0 int term_trace_num = 0; @@ -181,10 +191,8 @@ Lisp_Object ns_display_name_list; long context_menu_value = 0; /* display update */ -NSPoint last_mouse_motion_position; static NSRect last_mouse_glyph; static Time last_mouse_movement_time = 0; -static Lisp_Object last_mouse_motion_frame; static EmacsScroller *last_mouse_scroll_bar = nil; static struct frame *ns_updating_frame; static NSView *focus_view = NULL; @@ -194,9 +202,9 @@ static NSRect uRect; #endif static BOOL gsaved = NO; static BOOL ns_fake_keydown = NO; -int ns_tmp_flags; /* FIXME */ -struct nsfont_info *ns_tmp_font; /* FIXME */ +#ifdef NS_IMPL_COCOA static BOOL ns_menu_bar_is_hidden = NO; +#endif /*static int debug_lock = 0; */ /* event loop */ @@ -208,7 +216,7 @@ static NSTimer *scroll_repeat_entry = nil; static fd_set select_readfds, select_writefds; enum { SELECT_HAVE_READ = 1, SELECT_HAVE_WRITE = 2, SELECT_HAVE_TMO = 4 }; static int select_nfds = 0, select_valid = 0; -static EMACS_TIME select_timeout = { 0, 0 }; +static struct timespec select_timeout = { 0, 0 }; static int selfds[2] = { -1, -1 }; static pthread_mutex_t select_mutex; static int apploopnr = 0; @@ -228,6 +236,7 @@ static struct { NULL, 0, 0 }; +#ifdef NS_IMPL_COCOA /* * State for pending menu activation: * MENU_NONE Normal state @@ -243,9 +252,7 @@ static int menu_will_open_state = MENU_NONE; /* Saved position for menu click. */ static CGPoint menu_mouse_point; - -/* Title for the menu to open. */ -static char *menu_pending_title = 0; +#endif /* Convert modifiers in a NeXTstep event to emacs style modifiers. */ #define NS_FUNCTION_KEY_MASK 0x800000 @@ -303,8 +310,13 @@ static char *menu_pending_title = 0; /* This is a piece of code which is common to all the event handling methods. Maybe it should even be a function. */ #define EV_TRAILER(e) \ - { \ - XSETFRAME (emacs_event->frame_or_window, emacsframe); \ + { \ + XSETFRAME (emacs_event->frame_or_window, emacsframe); \ + EV_TRAILER2 (e); \ + } + +#define EV_TRAILER2(e) \ + { \ if (e) emacs_event->timestamp = EV_TIMESTAMP (e); \ if (q_event_ptr) \ { \ @@ -317,8 +329,6 @@ static char *menu_pending_title = 0; ns_send_appdefined (-1); \ } -void x_set_cursor_type (struct frame *, Lisp_Object, Lisp_Object); - /* TODO: get rid of need for these forward declarations */ static void ns_condemn_scroll_bars (struct frame *f); static void ns_judge_scroll_bars (struct frame *f); @@ -338,8 +348,8 @@ hold_event (struct input_event *event) { if (hold_event_q.cap == 0) hold_event_q.cap = 10; else hold_event_q.cap *= 2; - hold_event_q.q = (struct input_event *) - xrealloc (hold_event_q.q, hold_event_q.cap * sizeof (*hold_event_q.q)); + hold_event_q.q = + xrealloc (hold_event_q.q, hold_event_q.cap * sizeof *hold_event_q.q); } hold_event_q.q[hold_event_q.nr++] = *event; @@ -356,7 +366,7 @@ append2 (Lisp_Object list, Lisp_Object item) { Lisp_Object array[2]; array[0] = list; - array[1] = Fcons (item, Qnil); + array[1] = list1 (item); return Fnconc (2, &array[0]); } @@ -482,16 +492,16 @@ ns_timeout (int usecs) Blocking timer utility used by ns_ring_bell -------------------------------------------------------------------------- */ { - EMACS_TIME wakeup = add_emacs_time (current_emacs_time (), - make_emacs_time (0, usecs * 1000)); + struct timespec wakeup = timespec_add (current_timespec (), + make_timespec (0, usecs * 1000)); /* Keep waiting until past the time wakeup. */ while (1) { - EMACS_TIME timeout, now = current_emacs_time (); - if (EMACS_TIME_LE (wakeup, now)) + struct timespec timeout, now = current_timespec (); + if (timespec_cmp (wakeup, now) <= 0) break; - timeout = sub_emacs_time (wakeup, now); + timeout = timespec_sub (wakeup, now); /* Try to wait that long--but we might wake up sooner. */ pselect (0, NULL, NULL, NULL, &timeout, NULL); @@ -670,8 +680,6 @@ ns_update_begin (struct frame *f) -------------------------------------------------------------------------- */ { NSView *view = FRAME_NS_VIEW (f); - NSRect r = [view frame]; - NSBezierPath *bp; NSTRACE (ns_update_begin); ns_update_auto_hide_menu_bar (); @@ -683,9 +691,24 @@ ns_update_begin (struct frame *f) is for the minibuffer. But the display engine may draw more because we have set the frame as garbaged. So reset clip path to the whole view. */ - bp = [[NSBezierPath bezierPathWithRect: r] retain]; - [bp setClip]; - [bp release]; +#ifdef NS_IMPL_COCOA + { + NSBezierPath *bp; + NSRect r = [view frame]; + NSRect cr = [[view window] frame]; + /* If a large frame size is set, r may be larger than the window frame + before constrained. In that case don't change the clip path, as we + will clear in to the tool bar and title bar. */ + if (r.size.height + + FRAME_NS_TITLEBAR_HEIGHT (f) + + FRAME_TOOLBAR_HEIGHT (f) <= cr.size.height) + { + bp = [[NSBezierPath bezierPathWithRect: r] retain]; + [bp setClip]; + [bp release]; + } + } +#endif #ifdef NS_IMPL_GNUSTEP uRect = NSMakeRect (0, 0, 0, 0); @@ -701,10 +724,10 @@ ns_update_window_begin (struct window *w) -------------------------------------------------------------------------- */ { struct frame *f = XFRAME (WINDOW_FRAME (w)); - Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); + Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); + NSTRACE (ns_update_window_begin); - updated_window = w; - set_output_cursor (&w->cursor); + w->output_cursor = w->cursor; block_input (); @@ -726,15 +749,13 @@ ns_update_window_begin (struct window *w) static void -ns_update_window_end (struct window *w, int cursor_on_p, - int mouse_face_overwritten_p) +ns_update_window_end (struct window *w, bool cursor_on_p, + bool mouse_face_overwritten_p) /* -------------------------------------------------------------------------- Finished a grouped sequence of drawing calls external (RIF) call; for one window called before update_end -------------------------------------------------------------------------- */ { - Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame)); - /* note: this fn is nearly identical in all terms */ if (!w->pseudo_window_p) { @@ -742,8 +763,8 @@ ns_update_window_end (struct window *w, int cursor_on_p, if (cursor_on_p) display_and_set_cursor (w, 1, - output_cursor.hpos, output_cursor.vpos, - output_cursor.x, output_cursor.y); + w->output_cursor.hpos, w->output_cursor.vpos, + w->output_cursor.x, w->output_cursor.y); if (draw_window_fringes (w, 1)) x_draw_vertical_border (w); @@ -754,13 +775,8 @@ ns_update_window_end (struct window *w, int cursor_on_p, /* If a row with mouse-face was overwritten, arrange for frame_up_to_date to redisplay the mouse highlight. */ if (mouse_face_overwritten_p) - { - hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; - hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; - hlinfo->mouse_face_window = Qnil; - } + reset_mouse_highlight (MOUSE_HL_INFO (XFRAME (w->frame))); - updated_window = NULL; NSTRACE (update_window_end); } @@ -772,19 +788,12 @@ ns_update_end (struct frame *f) external (RIF) call; for whole frame, called after update_window_end -------------------------------------------------------------------------- */ { - NSView *view = FRAME_NS_VIEW (f); + EmacsView *view = FRAME_NS_VIEW (f); /* if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */ - MOUSE_HL_INFO (f)->mouse_face_defer = 0; - - block_input (); + MOUSE_HL_INFO (f)->mouse_face_defer = 0; -#ifdef NS_IMPL_GNUSTEP - /* trigger flush only in the rectangle we tracked as being drawn */ - [view unlockFocusNeedsFlush: NO]; -/*fprintf (stderr, " (%.0f, %.0f : %.0f x %.0f)", uRect.origin.x, uRect.origin.y, uRect.size.width, uRect.size.height); */ - [view lockFocusInRect: uRect]; -#endif + block_input (); [view unlockFocus]; [[view window] flushWindow]; @@ -794,18 +803,6 @@ ns_update_end (struct frame *f) NSTRACE (ns_update_end); } - -static void -ns_flush (struct frame *f) -/* -------------------------------------------------------------------------- - external (RIF) call - NS impl is no-op since currently we flush in ns_update_end and elsewhere - -------------------------------------------------------------------------- */ -{ - NSTRACE (ns_flush); -} - - static void ns_focus (struct frame *f, NSRect *r, int n) /* -------------------------------------------------------------------------- @@ -818,13 +815,6 @@ ns_focus (struct frame *f, NSRect *r, int n) -------------------------------------------------------------------------- */ { // NSTRACE (ns_focus); -#ifdef NS_IMPL_GNUSTEP - NSRect u; - if (n == 2) - u = NSUnionRect (r[0], r[1]); - else if (r) - u = *r; -#endif /* static int c =0; fprintf (stderr, "focus: %d", c++); if (r) fprintf (stderr, " (%.0f, %.0f : %.0f x %.0f)", r->origin.x, r->origin.y, r->size.width, r->size.height); @@ -843,33 +833,11 @@ ns_focus (struct frame *f, NSRect *r, int n) } if (view) -#ifdef NS_IMPL_GNUSTEP - r ? [view lockFocusInRect: u] : [view lockFocus]; -#else [view lockFocus]; -#endif focus_view = view; /*if (view) debug_lock++; */ } -#ifdef NS_IMPL_GNUSTEP - else - { - /* more than one rect being drawn into */ - if (view && r) - { - [view unlockFocus]; /* add prev rect to redraw list */ - [view lockFocusInRect: u]; /* focus for draw in new rect */ - } - } -#endif } -#ifdef NS_IMPL_GNUSTEP - else - { - /* in batch mode, but in GNUstep must still track rectangles explicitly */ - uRect = (r ? NSUnionRect (uRect, u) : [FRAME_NS_VIEW (f) visibleRect]); - } -#endif /* clipping */ if (r) @@ -912,7 +880,8 @@ ns_unfocus (struct frame *f) static void -ns_clip_to_row (struct window *w, struct glyph_row *row, int area, BOOL gc) +ns_clip_to_row (struct window *w, struct glyph_row *row, + enum glyph_row_area area, BOOL gc) /* -------------------------------------------------------------------------- Internal (but parallels other terms): Focus drawing on given row -------------------------------------------------------------------------- */ @@ -981,24 +950,6 @@ ns_ring_bell (struct frame *f) } } - -static void -ns_reset_terminal_modes (struct terminal *terminal) -/* Externally called as hook */ -{ - NSTRACE (ns_reset_terminal_modes); -} - - -static void -ns_set_terminal_modes (struct terminal *terminal) -/* Externally called as hook */ -{ - NSTRACE (ns_set_terminal_modes); -} - - - /* ========================================================================== Frame / window manager related functions @@ -1012,8 +963,9 @@ ns_raise_frame (struct frame *f) Bring window to foreground and make it active -------------------------------------------------------------------------- */ { - NSView *view = FRAME_NS_VIEW (f); - check_window_system (); + NSView *view; + check_window_system (f); + view = FRAME_NS_VIEW (f); block_input (); if (FRAME_VISIBLE_P (f)) [[view window] makeKeyAndOrderFront: NSApp]; @@ -1027,8 +979,9 @@ ns_lower_frame (struct frame *f) Send window to back -------------------------------------------------------------------------- */ { - NSView *view = FRAME_NS_VIEW (f); - check_window_system (); + NSView *view; + check_window_system (f); + view = FRAME_NS_VIEW (f); block_input (); [[view window] orderBack: NSApp]; unblock_input (); @@ -1056,7 +1009,7 @@ ns_frame_rehighlight (struct frame *frame) External (hook): called on things like window switching within frame -------------------------------------------------------------------------- */ { - struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (frame); + struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame); struct frame *old_highlight = dpyinfo->x_highlight_frame; NSTRACE (ns_frame_rehighlight); @@ -1131,9 +1084,10 @@ x_make_frame_invisible (struct frame *f) External: Hide the window (X11 semantics) -------------------------------------------------------------------------- */ { - NSView * view = FRAME_NS_VIEW (f); + NSView *view; NSTRACE (x_make_frame_invisible); - check_window_system (); + check_window_system (f); + view = FRAME_NS_VIEW (f); [[view window] orderOut: NSApp]; SET_FRAME_VISIBLE (f, 0); SET_FRAME_ICONIFIED (f, 0); @@ -1146,10 +1100,13 @@ x_iconify_frame (struct frame *f) External: Iconify window -------------------------------------------------------------------------- */ { - NSView * view = FRAME_NS_VIEW (f); - struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f); + NSView *view; + struct ns_display_info *dpyinfo; + NSTRACE (x_iconify_frame); - check_window_system (); + check_window_system (f); + view = FRAME_NS_VIEW (f); + dpyinfo = FRAME_DISPLAY_INFO (f); if (dpyinfo->x_highlight_frame == f) dpyinfo->x_highlight_frame = 0; @@ -1174,11 +1131,15 @@ x_iconify_frame (struct frame *f) void x_free_frame_resources (struct frame *f) { - NSView *view = FRAME_NS_VIEW (f); - struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f); - Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); + NSView *view; + struct ns_display_info *dpyinfo; + Mouse_HLInfo *hlinfo; + NSTRACE (x_free_frame_resources); - check_window_system (); + check_window_system (f); + view = FRAME_NS_VIEW (f); + dpyinfo = FRAME_DISPLAY_INFO (f); + hlinfo = MOUSE_HL_INFO (f); [(EmacsView *)view setWindowClosing: YES]; /* may not have been informed */ @@ -1194,12 +1155,7 @@ x_free_frame_resources (struct frame *f) if (f == dpyinfo->x_highlight_frame) dpyinfo->x_highlight_frame = 0; if (f == hlinfo->mouse_face_mouse_frame) - { - hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; - hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; - hlinfo->mouse_face_window = Qnil; - hlinfo->mouse_face_mouse_frame = 0; - } + reset_mouse_highlight (hlinfo); if (f->output_data.ns->miniimage != nil) [f->output_data.ns->miniimage release]; @@ -1219,7 +1175,7 @@ x_destroy_window (struct frame *f) -------------------------------------------------------------------------- */ { NSTRACE (x_destroy_window); - check_window_system (); + check_window_system (f); x_free_frame_resources (f); ns_window_num--; } @@ -1307,12 +1263,17 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows) /* If we have a toolbar, take its height into account. */ if (tb && ! [view isFullscreen]) + { /* NOTE: previously this would generate wrong result if toolbar not yet displayed and fixing toolbar_height=32 helped, but now (200903) seems no longer needed */ FRAME_TOOLBAR_HEIGHT (f) = NSHeight ([window frameRectForContentRect: NSMakeRect (0, 0, 0, 0)]) - FRAME_NS_TITLEBAR_HEIGHT (f); +#ifdef NS_IMPL_GNUSTEP + FRAME_TOOLBAR_HEIGHT (f) -= 3; +#endif + } else FRAME_TOOLBAR_HEIGHT (f) = 0; @@ -1364,7 +1325,7 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows) static void -ns_fullscreen_hook (FRAME_PTR f) +ns_fullscreen_hook (struct frame *f) { EmacsView *view = (EmacsView *)FRAME_NS_VIEW (f); @@ -1397,7 +1358,7 @@ ns_fullscreen_hook (FRAME_PTR f) NSColor * ns_lookup_indexed_color (unsigned long idx, struct frame *f) { - struct ns_color_table *color_table = FRAME_NS_DISPLAY_INFO (f)->color_table; + struct ns_color_table *color_table = FRAME_DISPLAY_INFO (f)->color_table; if (idx < 1 || idx >= color_table->avail) return nil; return color_table->colors[idx]; @@ -1407,7 +1368,7 @@ ns_lookup_indexed_color (unsigned long idx, struct frame *f) unsigned long ns_index_color (NSColor *color, struct frame *f) { - struct ns_color_table *color_table = FRAME_NS_DISPLAY_INFO (f)->color_table; + struct ns_color_table *color_table = FRAME_DISPLAY_INFO (f)->color_table; ptrdiff_t idx; ptrdiff_t i; @@ -1457,7 +1418,7 @@ ns_free_indexed_color (unsigned long idx, struct frame *f) if (!f) return; - color_table = FRAME_NS_DISPLAY_INFO (f)->color_table; + color_table = FRAME_DISPLAY_INFO (f)->color_table; if (idx <= 0 || idx >= color_table->size) { message1 ("ns_free_indexed_color: Color index out of range.\n"); @@ -1538,7 +1499,7 @@ ns_get_color (const char *name, NSColor **col) } } - if (r >= 0.0) + if (r >= 0.0F) { *col = [NSColor colorWithCalibratedRed: r green: g blue: b alpha: 1.0]; unblock_input (); @@ -1599,7 +1560,7 @@ ns_color_to_lisp (NSColor *col) Convert a color to a lisp string with the RGB equivalent -------------------------------------------------------------------------- */ { - CGFloat red, green, blue, alpha, gray; + EmacsCGFloat red, green, blue, alpha, gray; char buf[1024]; const char *str; NSTRACE (ns_color_to_lisp); @@ -1641,7 +1602,7 @@ ns_query_color(void *col, XColor *color_def, int setPixel) and set color_def pixel to the resulting index. -------------------------------------------------------------------------- */ { - CGFloat r, g, b, a; + EmacsCGFloat r, g, b, a; [((NSColor *)col) getRed: &r green: &g blue: &b alpha: &a]; color_def->red = r * 65535; @@ -1686,34 +1647,13 @@ ns_defined_color (struct frame *f, } -unsigned long -ns_get_rgb_color (struct frame *f, float r, float g, float b, float a) -/* -------------------------------------------------------------------------- - return an autoreleased RGB color - -------------------------------------------------------------------------- */ -{ -/*static int c = 1; fprintf (stderr, "color request %d\n", c++); */ - if (r < 0.0) r = 0.0; - else if (r > 1.0) r = 1.0; - if (g < 0.0) g = 0.0; - else if (g > 1.0) g = 1.0; - if (b < 0.0) b = 0.0; - else if (b > 1.0) b = 1.0; - if (a < 0.0) a = 0.0; - else if (a > 1.0) a = 1.0; - return (unsigned long) ns_index_color( - [NSColor colorWithCalibratedRed: r green: g blue: b alpha: a], f); -} - - void x_set_frame_alpha (struct frame *f) /* -------------------------------------------------------------------------- change the entire-frame transparency -------------------------------------------------------------------------- */ { - struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f); - EmacsView *view = FRAME_NS_VIEW (f); + struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); double alpha = 1.0; double alpha_min = 1.0; @@ -1735,7 +1675,10 @@ x_set_frame_alpha (struct frame *f) alpha = alpha_min; #ifdef NS_IMPL_COCOA + { + EmacsView *view = FRAME_NS_VIEW (f); [[view window] setAlphaValue: alpha]; + } #endif } @@ -1788,7 +1731,7 @@ x_set_mouse_position (struct frame *f, int h, int v) static int -note_mouse_movement (struct frame *frame, float x, float y) +note_mouse_movement (struct frame *frame, CGFloat x, CGFloat y) /* ------------------------------------------------------------------------ Called by EmacsView on mouseMovement events. Passes on to emacs mainstream code if we moved off of a rect of interest @@ -1797,7 +1740,7 @@ note_mouse_movement (struct frame *frame, float x, float y) { // NSTRACE (note_mouse_movement); - XSETFRAME (last_mouse_motion_frame, frame); + FRAME_DISPLAY_INFO (frame)->last_mouse_motion_frame = frame; /* Note, this doesn't get called for enter/leave, since we don't have a position. Those are taken care of in the corresponding NSView methods. */ @@ -1845,7 +1788,7 @@ ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, return; } - dpyinfo = FRAME_NS_DISPLAY_INFO (*fp); + dpyinfo = FRAME_DISPLAY_INFO (*fp); block_input (); @@ -1867,13 +1810,14 @@ ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, XFRAME (frame)->mouse_moved = 0; last_mouse_scroll_bar = nil; - if (last_mouse_frame && FRAME_LIVE_P (last_mouse_frame)) - f = last_mouse_frame; + if (dpyinfo->last_mouse_frame + && FRAME_LIVE_P (dpyinfo->last_mouse_frame)) + f = dpyinfo->last_mouse_frame; else f = dpyinfo->x_focus_frame ? dpyinfo->x_focus_frame : SELECTED_FRAME (); - if (f && f->output_data.ns) /* TODO: 2nd check no longer needed? */ + if (f && FRAME_NS_P (f)) { view = FRAME_NS_VIEW (*fp); @@ -1912,10 +1856,9 @@ ns_frame_up_to_date (struct frame *f) { block_input (); ns_update_begin(f); - if (hlinfo->mouse_face_mouse_frame) - note_mouse_highlight (hlinfo->mouse_face_mouse_frame, - hlinfo->mouse_face_mouse_x, - hlinfo->mouse_face_mouse_y); + note_mouse_highlight (hlinfo->mouse_face_mouse_frame, + hlinfo->mouse_face_mouse_x, + hlinfo->mouse_face_mouse_y); ns_update_end(f); unblock_input (); } @@ -2025,9 +1968,6 @@ ns_clear_frame (struct frame *f) mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f))); - output_cursor.hpos = output_cursor.vpos = 0; - output_cursor.x = -1; - r = [view bounds]; block_input (); @@ -2083,7 +2023,7 @@ ns_scroll_run (struct window *w, struct run *run) /* Get frame-relative bounding box of the text display area of W, without mode lines. Include in this box the left and right fringe of W. */ - window_box (w, -1, &x, &y, &width, &height); + window_box (w, ANY_AREA, &x, &y, &width, &height); from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y); to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y); @@ -2114,7 +2054,6 @@ ns_scroll_run (struct window *w, struct run *run) block_input (); - updated_window = w; x_clear_cursor (w); { @@ -2132,12 +2071,11 @@ ns_scroll_run (struct window *w, struct run *run) static void -ns_after_update_window_line (struct glyph_row *desired_row) +ns_after_update_window_line (struct window *w, struct glyph_row *desired_row) /* -------------------------------------------------------------------------- External (RIF): preparatory to fringe update after text was updated -------------------------------------------------------------------------- */ { - struct window *w = updated_window; struct frame *f; int width, height; @@ -2223,8 +2161,11 @@ ns_compute_glyph_string_overhangs (struct glyph_string *s) else { s->left_overhang = 0; - s->right_overhang = ((struct nsfont_info *)font)->ital ? - FONT_HEIGHT (font) * 0.2 : 0; + if (EQ (font->driver->type, Qns)) + s->right_overhang = ((struct nsfont_info *)font)->ital ? + FONT_HEIGHT (font) * 0.2 : 0; + else + s->right_overhang = 0; } } @@ -2247,7 +2188,6 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row, { struct frame *f = XFRAME (WINDOW_FRAME (w)); struct face *face = p->face; - int rowY; static EmacsImage **bimgs = NULL; static int nBimgs = 0; @@ -2261,8 +2201,7 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row, } /* Must clip because of partially visible lines. */ - rowY = WINDOW_TO_FRAME_PIXEL_Y (w, row->y); - ns_clip_to_row (w, row, -1, YES); + ns_clip_to_row (w, row, ANY_AREA, YES); if (!p->overlay_p) { @@ -2349,7 +2288,7 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row, [ns_lookup_indexed_color(face->background, f) set]; NSRectFill (r); [img setXBMColor: ns_lookup_indexed_color(face->foreground, f)]; -#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 [img drawInRect: r fromRect: NSZeroRect operation: NSCompositeSourceOver @@ -2370,8 +2309,8 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row, 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) + int x, int y, enum text_cursor_kinds cursor_type, + int cursor_width, bool on_p, bool active_p) /* -------------------------------------------------------------------------- External call (RIF): draw cursor. Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. @@ -2381,7 +2320,6 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int fx, fy, h, cursor_height; struct frame *f = WINDOW_XFRAME (w); struct glyph *phys_cursor_glyph; - int overspill; struct glyph *cursor_glyph; struct face *face; NSColor *hollow_color = FRAME_BACKGROUND_COLOR (f); @@ -2443,7 +2381,7 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, /* TODO: only needed in rare cases with last-resort font in HELLO.. should we do this more efficiently? */ - ns_clip_to_row (w, glyph_row, -1, NO); /* do ns_focus(f, &r, 1); if remove */ + ns_clip_to_row (w, glyph_row, ANY_AREA, NO); /* do ns_focus(f, &r, 1); if remove */ face = FACE_FROM_ID (f, phys_cursor_glyph->face_id); @@ -2588,7 +2526,7 @@ ns_get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr) --------------------------------------------------------------------- */ static void -ns_draw_underwave (struct glyph_string *s, CGFloat width, CGFloat x) +ns_draw_underwave (struct glyph_string *s, EmacsCGFloat width, EmacsCGFloat x) { int wave_height = 3, wave_length = 2; int y, dx, dy, odd, xmax; @@ -2606,7 +2544,7 @@ ns_draw_underwave (struct glyph_string *s, CGFloat width, CGFloat x) NSRectClip (waveClip); /* Draw the waves */ - a.x = x - ((int)(x) % dx) + 0.5; + a.x = x - ((int)(x) % dx) + (EmacsCGFloat) 0.5; b.x = a.x + dx; odd = (int)(a.x/dx) % 2; a.y = b.y = y + 0.5; @@ -2746,7 +2684,8 @@ ns_draw_text_decoration (struct glyph_string *s, struct face *face, } static void -ns_draw_box (NSRect r, float thickness, NSColor *col, char left_p, char right_p) +ns_draw_box (NSRect r, CGFloat thickness, NSColor *col, + char left_p, char right_p) /* -------------------------------------------------------------------------- Draw an unfilled rect inside r, optionally leaving left and/or right open. Note we can't just use an NSDrawRect command, because of the possibility @@ -2944,7 +2883,7 @@ ns_maybe_dumpglyphs_background (struct glyph_string *s, char force_p) : FRAME_BACKGROUND_COLOR (s->f)) set]; else { - struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (s->f); + struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (s->f); [[dpyinfo->bitmaps[face->stipple-1].img stippleMask] set]; } @@ -3023,7 +2962,7 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r) /* Draw the image.. do we need to draw placeholder if img ==nil? */ if (img != nil) { -#if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 NSRect dr = NSMakeRect (x, y, s->slice.width, s->slice.height); NSRect ir = NSMakeRect (s->slice.x, s->slice.y, s->slice.width, s->slice.height); @@ -3200,8 +3139,10 @@ ns_draw_glyph_string (struct glyph_string *s) { /* TODO (optimize): focus for box and contents draw */ NSRect r[2]; - int n; + int n, flags; char box_drawn_p = 0; + struct font *font = s->face->font; + if (! font) font = FRAME_FONT (s->f); NSTRACE (ns_draw_glyph_string); @@ -3268,13 +3209,10 @@ ns_draw_glyph_string (struct glyph_string *s) ns_maybe_dumpglyphs_background (s, s->first_glyph->type == COMPOSITE_GLYPH); - ns_tmp_flags = s->hl == DRAW_CURSOR ? NS_DUMPGLYPH_CURSOR : - (s->hl == DRAW_MOUSE_FACE ? NS_DUMPGLYPH_MOUSEFACE : - (s->for_overlaps ? NS_DUMPGLYPH_FOREGROUND : - NS_DUMPGLYPH_NORMAL)); - ns_tmp_font = (struct nsfont_info *)s->face->font; - if (ns_tmp_font == NULL) - ns_tmp_font = (struct nsfont_info *)FRAME_FONT (s->f); + flags = s->hl == DRAW_CURSOR ? NS_DUMPGLYPH_CURSOR : + (s->hl == DRAW_MOUSE_FACE ? NS_DUMPGLYPH_MOUSEFACE : + (s->for_overlaps ? NS_DUMPGLYPH_FOREGROUND : + NS_DUMPGLYPH_NORMAL)); if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR) { @@ -3283,10 +3221,21 @@ ns_draw_glyph_string (struct glyph_string *s) NS_FACE_FOREGROUND (s->face) = tmp; } - ns_tmp_font->font.driver->draw + font->driver->draw (s, 0, s->nchars, s->x, s->y, - (ns_tmp_flags == NS_DUMPGLYPH_NORMAL && !s->background_filled_p) - || ns_tmp_flags == NS_DUMPGLYPH_MOUSEFACE); + (flags == NS_DUMPGLYPH_NORMAL && !s->background_filled_p) + || flags == NS_DUMPGLYPH_MOUSEFACE); + + { + NSColor *col = (NS_FACE_FOREGROUND (s->face) != 0 + ? ns_lookup_indexed_color (NS_FACE_FOREGROUND (s->face), + s->f) + : FRAME_FOREGROUND_COLOR (s->f)); + [col set]; + + /* Draw underline, overline, strike-through. */ + ns_draw_text_decoration (s, s->face, col, s->width, s->x); + } if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR) { @@ -3348,6 +3297,19 @@ ns_send_appdefined (int value) { /*NSTRACE (ns_send_appdefined); */ +#ifdef NS_IMPL_GNUSTEP + // GNUStep needs postEvent to happen on the main thread. + if (! [[NSThread currentThread] isMainThread]) + { + EmacsApp *app = (EmacsApp *)NSApp; + app->nextappdefined = value; + [app performSelectorOnMainThread:@selector (sendFromMainThread:) + withObject:nil + waitUntilDone:YES]; + return; + } +#endif + /* Only post this event if we haven't already posted one. This will end the [NXApp run] main loop after having processed all events queued at this moment. */ @@ -3407,24 +3369,25 @@ check_native_fs () } #endif -const char * -ns_get_pending_menu_title () -{ - return menu_pending_title; -} - +/* GNUStep and OSX <= 10.4 does not have cancelTracking. */ +#if defined (NS_IMPL_COCOA) && \ + MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 /* Check if menu open should be cancelled or continued as normal. */ void ns_check_menu_open (NSMenu *menu) { - /* GNUStep and OSX <= 10.4 does not have cancelTracking. */ -#if defined(NS_IMPL_COCOA) && \ - MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - /* Click in menu bar? */ NSArray *a = [[NSApp mainMenu] itemArray]; int i; BOOL found = NO; + + if (menu == nil) // Menu tracking ended. + { + if (menu_will_open_state == MENU_OPENING) + menu_will_open_state = MENU_NONE; + return; + } + for (i = 0; ! found && i < [a count]; i++) found = menu == [[a objectAtIndex:i] submenu]; if (found) @@ -3442,22 +3405,18 @@ ns_check_menu_open (NSMenu *menu) CGEventRef ourEvent = CGEventCreate (NULL); menu_mouse_point = CGEventGetLocation (ourEvent); CFRelease (ourEvent); - xfree (menu_pending_title); - menu_pending_title = xstrdup ([[menu title] UTF8String]); } else if (menu_will_open_state == MENU_OPENING) { menu_will_open_state = MENU_NONE; } } -#endif } /* Redo saved menu click if state is MENU_PENDING. */ void ns_check_pending_open_menu () { -#ifdef NS_IMPL_COCOA if (menu_will_open_state == MENU_PENDING) { CGEventSourceRef source @@ -3474,9 +3433,8 @@ ns_check_pending_open_menu () menu_will_open_state = MENU_OPENING; } -#endif } - +#endif /* NS_IMPL_COCOA) && >= MAC_OS_X_VERSION_10_5 */ static int ns_read_socket (struct terminal *terminal, struct input_event *hold_quit) @@ -3560,7 +3518,8 @@ ns_read_socket (struct terminal *terminal, struct input_event *hold_quit) int ns_select (int nfds, fd_set *readfds, fd_set *writefds, - fd_set *exceptfds, EMACS_TIME *timeout, sigset_t *sigmask) + fd_set *exceptfds, struct timespec const *timeout, + sigset_t const *sigmask) /* -------------------------------------------------------------------------- Replacement for select, checking for events -------------------------------------------------------------------------- */ @@ -3625,12 +3584,12 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds, /* Inform fd_handler that select should be called */ c = 'g'; - emacs_write (selfds[1], &c, 1); + emacs_write_sig (selfds[1], &c, 1); } else if (nr == 0 && timeout) { /* No file descriptor, just a timeout, no need to wake fd_handler */ - double time = EMACS_TIME_TO_DOUBLE (*timeout); + double time = timespectod (*timeout); timed_entry = [[NSTimer scheduledTimerWithTimeInterval: time target: NSApp selector: @@ -3658,7 +3617,7 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds, if (nr > 0 && readfds) { c = 's'; - emacs_write (selfds[1], &c, 1); + emacs_write_sig (selfds[1], &c, 1); } unblock_input (); @@ -3686,7 +3645,6 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds, pthread_mutex_lock (&select_mutex); if (readfds) *readfds = select_readfds; if (writefds) *writefds = select_writefds; - if (timeout) *timeout = select_timeout; pthread_mutex_unlock (&select_mutex); result = t; } @@ -3744,7 +3702,7 @@ ns_set_vertical_scroll_bar (struct window *window, NSTRACE (ns_set_vertical_scroll_bar); /* Get dimensions. */ - window_box (window, -1, 0, &window_y, 0, &window_height); + window_box (window, ANY_AREA, 0, &window_y, 0, &window_height); top = window_y; height = window_height; width = WINDOW_CONFIG_SCROLL_BAR_COLS (window) * FRAME_COLUMN_WIDTH (f); @@ -3760,16 +3718,7 @@ ns_set_vertical_scroll_bar (struct window *window, v = [view frame]; r.origin.y = (v.size.height - r.size.height - r.origin.y); - if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (window)) - fringe_extended_p = (WINDOW_LEFTMOST_P (window) - && WINDOW_LEFT_FRINGE_WIDTH (window) - && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (window) - || WINDOW_LEFT_MARGIN_COLS (window) == 0)); - else - fringe_extended_p = (WINDOW_RIGHTMOST_P (window) - && WINDOW_RIGHT_FRINGE_WIDTH (window) - && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (window) - || WINDOW_RIGHT_MARGIN_COLS (window) == 0)); + fringe_extended_p = WINDOW_FRINGE_EXTENDED_P (window); XSETWINDOW (win, window); block_input (); @@ -3799,7 +3748,7 @@ ns_set_vertical_scroll_bar (struct window *window, } bar = [[EmacsScroller alloc] initFrame: r window: win]; - wset_vertical_scroll_bar (window, make_save_pointer (bar)); + wset_vertical_scroll_bar (window, make_save_ptr (bar)); } else { @@ -3885,15 +3834,6 @@ ns_judge_scroll_bars (struct frame *f) [eview updateFrameSize: NO]; } - -void -x_wm_set_icon_position (struct frame *f, int icon_x, int icon_y) -{ - /* XXX irrelevant under NS */ -} - - - /* ========================================================================== Initialization @@ -3903,15 +3843,31 @@ x_wm_set_icon_position (struct frame *f, int icon_x, int icon_y) int x_display_pixel_height (struct ns_display_info *dpyinfo) { - NSScreen *screen = [NSScreen mainScreen]; - return [screen frame].size.height; + NSArray *screens = [NSScreen screens]; + NSEnumerator *enumerator = [screens objectEnumerator]; + NSScreen *screen; + NSRect frame; + + frame = NSZeroRect; + while ((screen = [enumerator nextObject]) != nil) + frame = NSUnionRect (frame, [screen frame]); + + return NSHeight (frame); } int x_display_pixel_width (struct ns_display_info *dpyinfo) { - NSScreen *screen = [NSScreen mainScreen]; - return [screen frame].size.width; + NSArray *screens = [NSScreen screens]; + NSEnumerator *enumerator = [screens objectEnumerator]; + NSScreen *screen; + NSRect frame; + + frame = NSZeroRect; + while ((screen = [enumerator nextObject]) != nil) + frame = NSUnionRect (frame, [screen frame]); + + return NSWidth (frame); } @@ -3973,7 +3929,6 @@ ns_initialize_display_info (struct ns_display_info *dpyinfo) { NSScreen *screen = [NSScreen mainScreen]; NSWindowDepth depth = [screen depth]; - Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight; dpyinfo->resx = 72.27; /* used 75.0, but this makes pt == pixel, expected */ dpyinfo->resy = 72.27; @@ -3986,22 +3941,12 @@ ns_initialize_display_info (struct ns_display_info *dpyinfo) dpyinfo->color_table = xmalloc (sizeof *dpyinfo->color_table); dpyinfo->color_table->colors = NULL; dpyinfo->root_window = 42; /* a placeholder.. */ - - hlinfo->mouse_face_mouse_frame = NULL; - hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; - hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; - hlinfo->mouse_face_face_id = DEFAULT_FACE_ID; - hlinfo->mouse_face_window = hlinfo->mouse_face_overlay = Qnil; - hlinfo->mouse_face_hidden = 0; - - hlinfo->mouse_face_mouse_x = hlinfo->mouse_face_mouse_y = 0; - hlinfo->mouse_face_defer = 0; - dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame = NULL; - dpyinfo->n_fonts = 0; dpyinfo->smallest_font_height = 1; dpyinfo->smallest_char_width = 1; + + reset_mouse_highlight (&dpyinfo->mouse_highlight); } @@ -4022,9 +3967,7 @@ static struct redisplay_interface ns_redisplay_interface = ns_after_update_window_line, ns_update_window_begin, ns_update_window_end, - x_cursor_to, - ns_flush, - 0, /* flush_display_optional */ + 0, /* flush_display */ x_clear_window_mouse_face, x_get_glyph_overhangs, x_fix_overlapping_area, @@ -4032,7 +3975,7 @@ static struct redisplay_interface ns_redisplay_interface = 0, /* define_fringe_bitmap */ /* FIXME: simplify ns_draw_fringe_bitmap */ 0, /* destroy_fringe_bitmap */ ns_compute_glyph_string_overhangs, - ns_draw_glyph_string, /* interface to nsfont.m */ + ns_draw_glyph_string, ns_define_frame_cursor, ns_clear_frame_area, ns_draw_window_cursor, @@ -4089,8 +4032,8 @@ ns_create_terminal (struct ns_display_info *dpyinfo) terminal->ins_del_lines_hook = 0; /* XXX vestigial? */ terminal->delete_glyphs_hook = 0; /* XXX vestigial? */ terminal->ring_bell_hook = ns_ring_bell; - terminal->reset_terminal_modes_hook = ns_reset_terminal_modes; - terminal->set_terminal_modes_hook = ns_set_terminal_modes; + terminal->reset_terminal_modes_hook = NULL; + terminal->set_terminal_modes_hook = NULL; terminal->update_begin_hook = ns_update_begin; terminal->update_end_hook = ns_update_end; terminal->set_terminal_window_hook = NULL; /* XXX vestigial? */ @@ -4148,7 +4091,7 @@ ns_term_init (Lisp_Object display_name) if (selfds[0] == -1) { - if (pipe (selfds) == -1) + if (emacs_pipe (selfds) != 0) { fprintf (stderr, "Failed to create pipe: %s\n", emacs_strerror (errno)); @@ -4366,6 +4309,12 @@ ns_term_init (Lisp_Object display_name) [NSApp run]; ns_do_open_file = YES; + +#ifdef NS_IMPL_GNUSTEP + /* GNUstep steals SIGCHLD for use in NSTask, but we don't use NSTask. + We must re-catch it so subprocess works. */ + catch_child_signal (); +#endif return dpyinfo; } @@ -4416,19 +4365,37 @@ ns_term_shutdown (int sig) { int type = [theEvent type]; NSWindow *window = [theEvent window]; + /* NSTRACE (sendEvent); */ /*fprintf (stderr, "received event of type %d\t%d\n", type);*/ -#ifdef NS_IMPL_COCOA - if (type == NSApplicationDefined - && [theEvent data2] == NSAPP_DATA2_RUNASSCRIPT) +#ifdef NS_IMPL_GNUSTEP + // Keyboard events aren't propagated to file dialogs for some reason. + if ([NSApp modalWindow] != nil && + (type == NSKeyDown || type == NSKeyUp || type == NSFlagsChanged)) { - ns_run_ascript (); - [self stop: self]; + [[NSApp modalWindow] sendEvent: theEvent]; return; } #endif + if (type == NSApplicationDefined) + { + switch ([theEvent data2]) + { +#ifdef NS_IMPL_COCOA + case NSAPP_DATA2_RUNASSCRIPT: + ns_run_ascript (); + [self stop: self]; + return; +#endif + case NSAPP_DATA2_RUNFILEDIALOG: + ns_run_file_dialog (); + [self stop: self]; + return; + } + } + if (type == NSCursorUpdate && window == nil) { fprintf (stderr, "Dropping external cursor update event.\n"); @@ -4452,6 +4419,23 @@ ns_term_shutdown (int sig) } } + +#ifdef NS_IMPL_COCOA + /* If no dialog and none of our frames have focus and it is a move, skip it. + It is a mouse move in an auxiliary menu, i.e. on the top right on OSX, + such as Wifi, sound, date or similar. + This prevents "spooky" highlighting in the frame under the menu. */ + if (type == NSMouseMoved && [NSApp modalWindow] == nil) + { + struct ns_display_info *di; + BOOL has_focus = NO; + for (di = x_display_list; ! has_focus && di; di = di->next) + has_focus = di->x_focus_frame != 0; + if (! has_focus) + return; + } +#endif + [super sendEvent: theEvent]; } @@ -4673,6 +4657,13 @@ not_in_argv (NSString *arg) ns_send_appdefined (-2); } +#ifdef NS_IMPL_GNUSTEP +- (void)sendFromMainThread:(id)unused +{ + ns_send_appdefined (nextappdefined); +} +#endif + - (void)fd_handler:(id)unused /* -------------------------------------------------------------------------- Check data waiting on file descriptors and terminate if so @@ -4682,8 +4673,8 @@ not_in_argv (NSString *arg) int waiting = 1, nfds; char c; - SELECT_TYPE readfds, writefds, *wfds; - EMACS_TIME timeout, *tmo; + fd_set readfds, writefds, *wfds; + struct timespec timeout, *tmo; NSAutoreleasePool *pool = nil; /* NSTRACE (fd_handler); */ @@ -4695,7 +4686,7 @@ not_in_argv (NSString *arg) if (waiting) { - SELECT_TYPE fds; + fd_set fds; FD_ZERO (&fds); FD_SET (selfds[0], &fds); result = select (selfds[0]+1, &fds, NULL, NULL, NULL); @@ -4834,17 +4825,26 @@ not_in_argv (NSString *arg) /* called on font panel selection */ - (void)changeFont: (id)sender { - NSEvent *e =[[self window] currentEvent]; - struct face *face =FRAME_DEFAULT_FACE (emacsframe); + NSEvent *e = [[self window] currentEvent]; + struct face *face = FRAME_DEFAULT_FACE (emacsframe); + struct font *font = face->font; id newFont; - float size; + CGFloat size; + NSFont *nsfont; NSTRACE (changeFont); + if (!emacs_event) return; - if ((newFont = [sender convertFont: - ((struct nsfont_info *)face->font)->nsfont])) + if (EQ (font->driver->type, Qns)) + nsfont = ((struct nsfont_info *)font)->nsfont; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + else + nsfont = (NSFont *) macfont_get_nsctfont (font); +#endif + + if ((newFont = [sender convertFont: nsfont])) { SET_FRAME_GARBAGED (emacsframe); /* now needed as of 2008/10 */ @@ -4956,7 +4956,16 @@ not_in_argv (NSString *arg) { /* COUNTERHACK: map 'Delete' on upper-right main KB to 'Backspace', because Emacs treats Delete and KP-Delete same (in simple.el). */ - if (fnKeysym == 0xFFFF && [theEvent keyCode] == 0x33) + if ((fnKeysym == 0xFFFF && [theEvent keyCode] == 0x33) +#ifdef NS_IMPL_GNUSTEP + /* GNUstep uses incompatible keycodes, even for those that are + supposed to be hardware independent. Just check for delete. + Keypad delete does not have keysym 0xFFFF. + See http://savannah.gnu.org/bugs/?25395 + */ + || (fnKeysym == 0xFFFF && code == 127) +#endif + ) code = 0xFF08; /* backspace */ else code = fnKeysym; @@ -5109,10 +5118,14 @@ not_in_argv (NSString *arg) #if !defined (NS_IMPL_COCOA) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 /* if we get here we should send the key for input manager processing */ + /* Disable warning, there is nothing a user can do about it anyway, and + it does not seem to matter. */ +#if 0 if (firstTime && [[NSInputManager currentInputManager] wantsToDelayTextChangeNotifications] == NO) fprintf (stderr, "Emacs: WARNING: TextInput mgr wants marked text to be permanent!\n"); +#endif firstTime = NO; #endif if (NS_KEYLOG && !processingCompose) @@ -5320,7 +5333,12 @@ not_in_argv (NSString *arg) return NSMakeRange (NSNotFound, 0); } +#if defined (NS_IMPL_COCOA) || GNUSTEP_GUI_MAJOR_VERSION > 0 || \ + GNUSTEP_GUI_MINOR_VERSION > 22 - (NSUInteger)characterIndexForPoint: (NSPoint)thePoint +#else +- (unsigned int)characterIndexForPoint: (NSPoint)thePoint +#endif { if (NS_KEYLOG) NSLog (@"characterIndexForPoint request"); @@ -5343,6 +5361,7 @@ not_in_argv (NSString *arg) /* This is what happens when the user presses a mouse button. */ - (void)mouseDown: (NSEvent *)theEvent { + struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe); NSPoint p = [self convertPoint: [theEvent locationInWindow] fromView: nil]; NSTRACE (mouseDown); @@ -5352,14 +5371,14 @@ not_in_argv (NSString *arg) if (!emacs_event) return; - last_mouse_frame = emacsframe; + dpyinfo->last_mouse_frame = emacsframe; /* appears to be needed to prevent spurious movement events generated on button clicks */ - last_mouse_frame->mouse_moved = 0; + emacsframe->mouse_moved = 0; if ([theEvent type] == NSScrollWheel) { - float delta = [theEvent deltaY]; + CGFloat delta = [theEvent deltaY]; /* Mac notebooks send wheel events w/delta =0 when trackpad scrolling */ if (delta == 0) return; @@ -5427,13 +5446,16 @@ not_in_argv (NSString *arg) - (void)mouseMoved: (NSEvent *)e { Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (emacsframe); + struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe); Lisp_Object frame; + NSPoint pt; // NSTRACE (mouseMoved); last_mouse_movement_time = EV_TIMESTAMP (e); - last_mouse_motion_position - = [self convertPoint: [e locationInWindow] fromView: nil]; + pt = [self convertPoint: [e locationInWindow] fromView: nil]; + dpyinfo->last_mouse_motion_x = pt.x; + dpyinfo->last_mouse_motion_y = pt.y; /* update any mouse face */ if (hlinfo->mouse_face_hidden) @@ -5446,8 +5468,30 @@ not_in_argv (NSString *arg) previous_help_echo_string = help_echo_string; help_echo_string = Qnil; - if (!note_mouse_movement (emacsframe, last_mouse_motion_position.x, - last_mouse_motion_position.y)) + if (!NILP (Vmouse_autoselect_window)) + { + NSTRACE (mouse_autoselect_window); + static Lisp_Object last_mouse_window; + Lisp_Object window + = window_from_coordinates (emacsframe, pt.x, pt.y, 0, 0); + + if (WINDOWP (window) + && !EQ (window, last_mouse_window) + && !EQ (window, selected_window) + && (focus_follows_mouse + || (EQ (XWINDOW (window)->frame, + XWINDOW (selected_window)->frame)))) + { + NSTRACE (in_window); + emacs_event->kind = SELECT_WINDOW_EVENT; + emacs_event->frame_or_window = window; + EV_TRAILER2 (e); + } + /* Remember the last window where we saw the mouse. */ + last_mouse_window = window; + } + + if (!note_mouse_movement (emacsframe, pt.x, pt.y)) help_echo_string = previous_help_echo_string; XSETFRAME (frame, emacsframe); @@ -5543,7 +5587,6 @@ not_in_argv (NSString *arg) if (oldr != rows || oldc != cols || neww != oldw || newh != oldh) { - struct frame *f = emacsframe; NSView *view = FRAME_NS_VIEW (emacsframe); NSWindow *win = [view window]; NSSize sz = [win resizeIncrements]; @@ -5576,7 +5619,7 @@ not_in_argv (NSString *arg) #ifdef NS_IMPL_GNUSTEP gsextra = 3; #endif - + NSTRACE (windowWillResize); /*fprintf (stderr,"Window will resize: %.0f x %.0f\n",frameSize.width,frameSize.height); */ @@ -5614,17 +5657,17 @@ not_in_argv (NSString *arg) old_title = 0; } } - else + else if (fs_state == FULLSCREEN_NONE && ! maximizing_resize) { char *size_title; NSWindow *window = [self window]; if (old_title == 0) { - const char *t = [[[self window] title] UTF8String]; + char *t = strdup ([[[self window] title] UTF8String]); char *pos = strstr (t, " — "); if (pos) *pos = '\0'; - old_title = xstrdup (t); + old_title = t; } size_title = xmalloc (strlen (old_title) + 40); esprintf (size_title, "%s — (%d x %d)", old_title, cols, rows); @@ -5642,7 +5685,7 @@ not_in_argv (NSString *arg) - (void)windowDidResize: (NSNotification *)notification { - if (! [self fsIsNative]) + if (! [self fsIsNative]) { NSWindow *theWindow = [notification object]; /* We can get notification on the non-FS window when in @@ -5663,27 +5706,33 @@ not_in_argv (NSString *arg) NSTRACE (windowDidResize); /*fprintf (stderr,"windowDidResize: %.0f\n",[theWindow frame].size.height); */ +if (cols > 0 && rows > 0) + { + [self updateFrameSize: YES]; + } + + ns_send_appdefined (-1); +} + #ifdef NS_IMPL_COCOA +- (void)viewDidEndLiveResize +{ + [super viewDidEndLiveResize]; if (old_title != 0) { + [[self window] setTitle: [NSString stringWithUTF8String: old_title]]; xfree (old_title); old_title = 0; } -#endif /* NS_IMPL_COCOA */ - - if (cols > 0 && rows > 0) - { - [self updateFrameSize: YES]; - } - - ns_send_appdefined (-1); + maximizing_resize = NO; } +#endif /* NS_IMPL_COCOA */ - (void)windowDidBecomeKey: (NSNotification *)notification /* cf. x_detect_focus_change(), x_focus_changed(), x_new_focus_frame() */ { - struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe); + struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe); struct frame *old_focus = dpyinfo->x_focus_frame; NSTRACE (windowDidBecomeKey); @@ -5704,10 +5753,11 @@ not_in_argv (NSString *arg) - (void)windowDidResignKey: (NSNotification *)notification /* cf. x_detect_focus_change(), x_focus_changed(), x_new_focus_frame() */ { - struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe); + struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (emacsframe); + BOOL is_focus_frame = dpyinfo->x_focus_frame == emacsframe; NSTRACE (windowDidResignKey); - if (dpyinfo->x_focus_frame == emacsframe) + if (is_focus_frame) dpyinfo->x_focus_frame = 0; ns_frame_rehighlight (emacsframe); @@ -5720,10 +5770,10 @@ not_in_argv (NSString *arg) x_set_frame_alpha (emacsframe); } - if (emacs_event) + if (emacs_event && is_focus_frame) { [self deleteWorkingText]; - emacs_event->kind = FOCUS_IN_EVENT; + emacs_event->kind = FOCUS_OUT_EVENT; EV_TRAILER ((id)nil); } } @@ -5752,7 +5802,6 @@ not_in_argv (NSString *arg) NSRect r, wr; Lisp_Object tem; NSWindow *win; - NSButton *toggleButton; NSSize sz; NSColor *col; NSString *name; @@ -5782,7 +5831,10 @@ not_in_argv (NSString *arg) FRAME_NS_VIEW (f) = self; emacsframe = f; +#ifdef NS_IMPL_COCOA old_title = 0; + maximizing_resize = NO; +#endif win = [[EmacsWindow alloc] initWithContentRect: r @@ -5828,9 +5880,12 @@ not_in_argv (NSString *arg) [win setToolbar: toolbar]; [toolbar setVisible: NO]; #ifdef NS_IMPL_COCOA + { + NSButton *toggleButton; toggleButton = [win standardWindowButton: NSWindowToolbarButton]; [toggleButton setTarget: self]; [toggleButton setAction: @selector (toggleToolbar: )]; + } #endif FRAME_TOOLBAR_HEIGHT (f) = 0; @@ -5854,7 +5909,7 @@ not_in_argv (NSString *arg) col = ns_lookup_indexed_color (NS_FACE_BACKGROUND (FRAME_DEFAULT_FACE (emacsframe)), emacsframe); [win setBackgroundColor: col]; - if ([col alphaComponent] != 1.0) + if ([col alphaComponent] != (EmacsCGFloat) 1.0) [win setOpaque: NO]; [self allocateGState]; @@ -5922,6 +5977,9 @@ not_in_argv (NSString *arg) maximized_width = -1; result.origin.y = defaultFrame.origin.y; [self setFSValue: FULLSCREEN_HEIGHT]; +#ifdef NS_IMPL_COCOA + maximizing_resize = YES; +#endif } else if (next_maximized == FULLSCREEN_WIDTH) { @@ -5940,14 +5998,20 @@ not_in_argv (NSString *arg) maximized_width = result.size.width; maximized_height = result.size.height; [self setFSValue: FULLSCREEN_MAXIMIZED]; +#ifdef NS_IMPL_COCOA + maximizing_resize = YES; +#endif } else { /* restore */ result = ns_userRect.size.height ? ns_userRect : result; ns_userRect = NSMakeRect (0, 0, 0, 0); +#ifdef NS_IMPL_COCOA + maximizing_resize = fs_state != FULLSCREEN_NONE; +#endif [self setFSValue: FULLSCREEN_NONE]; - maximized_width = maximized_width = -1; + maximized_width = maximized_height = -1; } if (fs_before_fs == -1) next_maximized = -1; @@ -6040,7 +6104,9 @@ not_in_argv (NSString *arg) { [self setFSValue: fs_before_fs]; fs_before_fs = -1; +#ifdef NS_IMPL_COCOA [self updateCollectionBehaviour]; +#endif if (FRAME_EXTERNAL_TOOL_BAR (emacsframe)) { [toolbar setVisible:YES]; @@ -6087,7 +6153,7 @@ not_in_argv (NSString *arg) } } #endif - + - (void)toggleFullScreen: (id)sender { NSWindow *w, *fw; @@ -6099,7 +6165,9 @@ not_in_argv (NSString *arg) if (fs_is_native) { +#ifdef NS_IMPL_COCOA [[self window] toggleFullScreen:sender]; +#endif return; } @@ -6145,7 +6213,7 @@ not_in_argv (NSString *arg) [fw useOptimizedDrawing: YES]; [fw setResizeIncrements: sz]; [fw setBackgroundColor: col]; - if ([col alphaComponent] != 1.0) + if ([col alphaComponent] != (EmacsCGFloat) 1.0) [fw setOpaque: NO]; f->border_width = 0; @@ -6183,7 +6251,7 @@ not_in_argv (NSString *arg) [w setContentView:[fw contentView]]; [w setResizeIncrements: sz]; [w setBackgroundColor: col]; - if ([col alphaComponent] != 1.0) + if ([col alphaComponent] != (EmacsCGFloat) 1.0) [w setOpaque: NO]; f->border_width = bwidth; @@ -6877,10 +6945,11 @@ not_in_argv (NSString *arg) } else { - float pos, por; + float pos; + CGFloat por; portion = max ((float)whole*min_portion/pixel_height, portion); pos = (float)position / (whole - portion); - por = (float)portion/whole; + por = (CGFloat)portion/whole; #if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 [self setKnobProportion: por]; [self setDoubleValue: pos]; @@ -6905,7 +6974,7 @@ not_in_argv (NSString *arg) *part = last_hit_part; *window = win; XSETINT (*y, pixel_height); - if ([self floatValue] > 0.999) + if ([self floatValue] > 0.999F) XSETINT (*x, pixel_height); else XSETINT (*x, pixel_height * [self floatValue]); @@ -6979,7 +7048,7 @@ not_in_argv (NSString *arg) NSRect sr, kr; /* hitPart is only updated AFTER event is passed on */ NSScrollerPart part = [self testPart: [e locationInWindow]]; - double inc = 0.0, loc, kloc, pos; + CGFloat inc = 0.0, loc, kloc, pos; int edge = 0; NSTRACE (EmacsScroller_mouseDown); @@ -7078,7 +7147,6 @@ not_in_argv (NSString *arg) { NSRect sr; double loc, pos; - int edge = 0; NSTRACE (EmacsScroller_mouseDragged); @@ -7089,15 +7157,13 @@ not_in_argv (NSString *arg) if (loc <= 0.0) { loc = 0.0; - edge = -1; } else if (loc >= NSHeight (sr) + last_mouse_offset) { loc = NSHeight (sr) + last_mouse_offset; - edge = 1; } - pos = /*(edge ? loc :*/ (loc - last_mouse_offset) / NSHeight (sr); + pos = (loc - last_mouse_offset) / NSHeight (sr); [self sendScrollEventAtLoc: pos fromEvent: e]; } @@ -7124,6 +7190,12 @@ not_in_argv (NSString *arg) @end /* EmacsScroller */ +#ifdef NS_IMPL_GNUSTEP +/* Dummy class to get rid of startup warnings. */ +@implementation EmacsDocument + +@end +#endif /* ========================================================================== @@ -7343,9 +7415,6 @@ allowing it to be used at a lower level for accented character entry."); staticpro (&ns_display_name_list); ns_display_name_list = Qnil; - staticpro (&last_mouse_motion_frame); - last_mouse_motion_frame = 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. */); @@ -7388,6 +7457,14 @@ variable `x-use-underline-position-properties', which is usually at the baseline level. The default value is nil. */); x_underline_at_descent_line = 0; - /* Tell emacs about this window system. */ - Fprovide (intern ("ns"), Qnil); + /* Tell Emacs about this window system. */ + Fprovide (Qns, Qnil); + + syms_of_nsfont (); +#ifdef NS_IMPL_COCOA +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 + syms_of_macfont (); +#endif +#endif + }