X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/365bac35a5ff56d76207a5130c7746b085172cee..62e62ea8662b533692802ff72ac5156dba9b4d4a:/src/nsterm.m diff --git a/src/nsterm.m b/src/nsterm.m index 3e58286146..7b9cebac87 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -78,6 +78,7 @@ int term_trace_num = 0; #define KEY_NS_INSERT_WORKING_TEXT ((1<<28)|(0<<16)|9) #define KEY_NS_DELETE_WORKING_TEXT ((1<<28)|(0<<16)|10) #define KEY_NS_SPI_SERVICE_CALL ((1<<28)|(0<<16)|11) +#define KEY_NS_NEW_FRAME ((1<<28)|(0<<16)|12) /* Convert a symbol indexed with an NSxxx value to a value as defined in keyboard.c (lispy_function_key). I hope this is a correct way @@ -140,7 +141,7 @@ Lisp_Object ns_input_color, ns_input_text, ns_working_text; Lisp_Object ns_input_spi_name, ns_input_spi_arg; Lisp_Object Vx_toolkit_scroll_bars; static Lisp_Object Qmodifier_value; -/*PENDING: unsure why these defined in term files, anyway we need in keymap.c */ +/* TODO: unsure why these defined in term files, anyway we need in keymap.c */ Lisp_Object Qalt, Qcontrol, Qhyper, Qmeta, Qsuper; extern Lisp_Object Qcursor_color, Qcursor_type, Qns; @@ -167,13 +168,6 @@ Lisp_Object ns_control_modifier; the Function modifer (laptops). May be any of the modifier lisp symbols. */ Lisp_Object ns_function_modifier; -/* A floating point value specifying the rate at which to blink the cursor. - YES indicates 0.5, NO indicates no blinking. */ -Lisp_Object ns_cursor_blink_rate; - -/* Used for liason with core emacs cursor-blink-mode. */ -Lisp_Object ns_cursor_blink_mode; - /* A floating point value specifying vertical stretch (positive) or shrink (negative) of text line spacing. Zero means default spacing. YES indicates 0.5, NO indicates 0.0. */ @@ -215,8 +209,8 @@ static int ns_window_num =0; static NSRect uRect; static BOOL gsaved = NO; BOOL ns_in_resize = NO; -int ns_tmp_flags; /*PENDING */ -struct nsfont_info *ns_tmp_font; /*PENDING */ +int ns_tmp_flags; /* FIXME */ +struct nsfont_info *ns_tmp_font; /* FIXME */ /*static int debug_lock = 0; */ #ifdef NS_IMPL_COCOA @@ -234,7 +228,6 @@ static BOOL send_appdefined = YES; static NSEvent *last_appdefined_event = 0; static NSTimer *timed_entry = 0; static NSTimer *fd_entry = nil; -static NSTimer *cursor_blink_entry = nil; static NSTimer *scroll_repeat_entry = nil; static fd_set select_readfds, t_readfds; static struct timeval select_timeout; @@ -297,13 +290,13 @@ static BOOL inNsSelect = 0; ns_send_appdefined (-1); \ } -/*PENDING: get rid of need for these forward declarations */ +/* TODO: get rid of need for these forward declarations */ static void ns_condemn_scroll_bars (struct frame *f), ns_judge_scroll_bars (struct frame *f); /* unused variables needed for compatibility reasons */ int x_use_underline_position_properties, x_underline_at_descent_line; -/* PENDING: figure out what to do with underline_minimum_offset. */ +/* FIXME: figure out what to do with underline_minimum_offset. */ /* ========================================================================== @@ -413,7 +406,6 @@ ns_init_paths () } } - /*PENDING: append to INFOPATH... */ if (!getenv ("INFOPATH")) { resourcePath = [resourceDir stringByAppendingPathComponent: @"info"]; @@ -555,7 +547,6 @@ ns_update_begin (struct frame *f) { NSView *view = FRAME_NS_VIEW (f); NSTRACE (ns_update_begin); -/*fprintf (stderr, "\\%p\n", f); */ ns_updating_frame = f; [view lockFocus]; @@ -691,7 +682,7 @@ ns_focus (struct frame *f, NSRect *r, int n) the entire window. -------------------------------------------------------------------------- */ { - NSTRACE (ns_focus); +// NSTRACE (ns_focus); #ifdef NS_IMPL_GNUSTEP NSRect u; if (n == 2) @@ -764,7 +755,7 @@ ns_unfocus (struct frame *f) Internal: Remove focus on given frame -------------------------------------------------------------------------- */ { - NSTRACE (ns_unfocus); +// NSTRACE (ns_unfocus); if (gsaved) { @@ -786,7 +777,7 @@ ns_unfocus (struct frame *f) static void -ns_clip_to_row (struct window *w, struct glyph_row *row, int area, GC gc) +ns_clip_to_row (struct window *w, struct glyph_row *row, int area, BOOL gc) /* -------------------------------------------------------------------------- 23: Internal (but parallels other terms): Focus drawing on given row -------------------------------------------------------------------------- */ @@ -847,7 +838,7 @@ ns_ring_bell () r.origin.y += (r.size.height - dim.y) / 2; r.size.width = dim.x; r.size.height = dim.y; - /* PENDING: cacheImageInRect under GNUSTEP does not account for + /* XXX: cacheImageInRect under GNUstep does not account for offset in x_set_window_size, so overestimate (4 fine on Cocoa) */ surr = NSInsetRect (r, -10, -10); ns_focus (frame, &surr, 1); @@ -965,17 +956,10 @@ ns_frame_rehighlight (struct frame *frame) if (dpyinfo->x_highlight_frame && dpyinfo->x_highlight_frame != old_highlight) { - /* as of 20080602 the lower and raise are superfluous */ if (old_highlight) - { - /*ns_lower_frame (old_highlight); */ x_update_cursor (old_highlight, 1); - } if (dpyinfo->x_highlight_frame) - { - /*ns_raise_frame (dpyinfo->x_highlight_frame); */ x_update_cursor (dpyinfo->x_highlight_frame, 1); - } } } @@ -987,7 +971,7 @@ x_make_frame_visible (struct frame *f) -------------------------------------------------------------------------- */ { NSTRACE (x_make_frame_visible); - /* PENDING: at some points in past this was not needed, as the only place that + /* XXX: at some points in past this was not needed, as the only place that called this (frame.c:Fraise_frame ()) also called raise_lower; if this ends up the case again, comment this out again. */ if (!FRAME_VISIBLE_P (f)) @@ -1158,8 +1142,8 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows) /* If we have a change in toolbar display, calculate height */ if (tb) - /* PENDING: GNUstep has not yet implemented the first method below, added - in Panther, however the second is incorrect under Cocoa. */ + /* XXX: GNUstep has not yet implemented the first method below, added + in Panther, however the second is incorrect under Cocoa. */ #ifdef NS_IMPL_GNUSTEP FRAME_NS_TOOLBAR_HEIGHT (f) = NSHeight ([NSWindow frameRectForContentRect: NSMakeRect (0, 0, 0, 0) @@ -1235,12 +1219,14 @@ x_set_window_size (struct frame *f, int change_grav, int cols, int rows) } + /* ========================================================================== Color management ========================================================================== */ + NSColor * ns_lookup_indexed_color (unsigned long idx, struct frame *f) { @@ -1359,9 +1345,9 @@ ns_get_color (const char *name, NSColor **col) return 0; } - /* 23: PENDING: emacs seems to downcase everything before passing it here, - which we can work around, except for GRAY, since gray##, where ## is - decimal between 0 and 99, is also an X11 colorname. */ + /* 23: FIXME: emacs seems to downcase everything before passing it here, + which we can work around, except for GRAY, since gray##, where ## is + decimal between 0 and 99, is also an X11 colorname. */ if (name[0] == '#') /* X11 format */ { hex = name + 1; @@ -1459,17 +1445,13 @@ ns_get_color (const char *name, NSColor **col) NSEnumerator *lenum, *cenum; NSString *name; NSColorList *clist; + #ifdef NS_IMPL_GNUSTEP - /* PENDING: who is wrong, the requestor or the implementation? */ + /* XXX: who is wrong, the requestor or the implementation? */ if ([nsname compare: @"Highlight" options: NSCaseInsensitiveSearch] == NSOrderedSame) nsname = @"highlightColor"; #endif - if ([nsname compare: @"dark blue" options: NSCaseInsensitiveSearch] - == NSOrderedSame - || [nsname compare: @"darkblue" options: NSCaseInsensitiveSearch] - == NSOrderedSame) - nsname = @"navy blue"; lenum = [[NSColorList availableColorLists] objectEnumerator]; while ( (clist = [lenum nextObject]) && new == nil) @@ -1585,7 +1567,7 @@ ns_defined_color (struct frame *f, char *name, XColor *color_def, int alloc, return 0; if (makeIndex && alloc) - color_def->pixel = ns_index_color(temp, f);//[temp retain]; + color_def->pixel = ns_index_color(temp, f); /* [temp retain]; */ [temp getRed: &r green: &g blue: &b alpha: &a]; color_def->red = r * 256; @@ -1638,7 +1620,7 @@ x_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y) NSTRACE (x_set_mouse_pixel_position); ns_raise_frame (f); #if 0 - /*PENDING: this does not work, and what about GNUstep? */ + /* FIXME: this does not work, and what about GNUstep? */ #ifdef NS_IMPL_COCOA [FRAME_NS_VIEW (f) lockFocus]; PSsetmouse ((float)pix_x, (float)pix_y); @@ -1677,7 +1659,7 @@ note_mouse_movement (struct frame *frame, float x, float y) known as last_mouse_glyph. ------------------------------------------------------------------------ */ { - NSTRACE (note_mouse_movement); +// NSTRACE (note_mouse_movement); XSETFRAME (last_mouse_motion_frame, frame); @@ -1732,8 +1714,8 @@ ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, if (last_mouse_scroll_bar != nil && insist == 0) { - /* PENDING: we do not use this path at the moment because drag events will - go directly to the EmacsScroller. Leaving code in for now. */ + /* TODO: we do not use this path at the moment because drag events will + go directly to the EmacsScroller. Leaving code in for now. */ [last_mouse_scroll_bar getMouseMotionPart: (int *)part window: bar_window x: x y: y]; if (time) *time = last_mouse_movement_time; @@ -1754,7 +1736,7 @@ ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, f = dpyinfo->x_focus_frame ? dpyinfo->x_focus_frame : SELECTED_FRAME (); - if (f && f->output_data.ns) /*PENDING: 2nd check no longer needed? */ + if (f && f->output_data.ns) /* TODO: 2nd check no longer needed? */ { view = FRAME_NS_VIEW (*fp); @@ -1940,6 +1922,8 @@ ns_clear_frame_area (struct frame *f, int x, int y, int width, int height) if (!view || !face) return; + NSTRACE (ns_clear_frame_area); + r = NSIntersectionRect (r, [view frame]); ns_focus (f, &r, 1); [ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f) set]; @@ -2213,7 +2197,7 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row, int oldVH = row->visible_height; row->visible_height = p->h; row->y -= rowY - p->y; - ns_clip_to_row (w, row, -1, NULL); + ns_clip_to_row (w, row, -1, NO); row->y = oldY; row->visible_height = oldVH; } @@ -2274,22 +2258,26 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int on_p, int active_p) /* -------------------------------------------------------------------------- External call (RIF): draw cursor + (modeled after x_draw_window_cursor + FIXME: cursor_width is effectively bogus -- it sometimes gets set + in xdisp.c set_frame_cursor_types, sometimes left uninitialized; + DON'T USE IT (no other terms do) -------------------------------------------------------------------------- */ { NSRect r, s; int fx, fy, h; struct frame *f = WINDOW_XFRAME (w); struct glyph *phys_cursor_glyph; - int overspill; - unsigned char drawGlyph = 0, cursorType, oldCursorType; + int overspill, cursorToDraw; NSTRACE (dumpcursor); +//fprintf(stderr, "drawcursor (%d,%d) activep = %d\tonp = %d\tc_type = %d\twidth = %d\n",x,y, active_p,on_p,cursor_type,cursor_width); if (!on_p) - return; + return; w->phys_cursor_type = cursor_type; - w->phys_cursor_on_p = 1; + w->phys_cursor_on_p = on_p; if (cursor_type == NO_CURSOR) { @@ -2314,7 +2302,7 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, r.size.height = h; r.size.width = w->phys_cursor_width; - /* PENDING: if we overwrite the internal border area, it does not get erased; + /* FIXME: if we overwrite the internal border area, it does not get erased; fix by truncating cursor, but better would be to erase properly */ overspill = r.origin.x + r.size.width - WINDOW_TEXT_TO_FRAME_PIXEL_X (w, WINDOW_BOX_RIGHT_EDGE_X (w) @@ -2322,75 +2310,57 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, if (overspill > 0) r.size.width -= overspill; - /* PENDING: 23: use emacs stored f->cursor_type instead of ns-specific */ - oldCursorType = FRAME_CURSOR (f); - cursorType = FRAME_CURSOR (f) = FRAME_NEW_CURSOR (f); - f->output_data.ns->current_cursor_color - = f->output_data.ns->desired_cursor_color; - - /* PENDING: only needed in rare cases with last-resort font in HELLO.. + /* 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, NULL); -/* ns_focus (f, &r, 1); */ - - if (FRAME_LAST_INACTIVE (f)) - { - /* previously hollow box; clear entire area */ - [FRAME_BACKGROUND_COLOR (f) set]; - NSRectFill (r); - drawGlyph = 1; - FRAME_LAST_INACTIVE (f) = NO; - } - - /* prepare to draw */ - if (cursorType == no_highlight || cursor_type == NO_CURSOR) - { - /* clearing for blink: erase the cursor itself */ - [FRAME_BACKGROUND_COLOR (f) set]; - cursorType = oldCursorType; /* just clear what we had before */ - } - else - [FRAME_CURSOR_COLOR (f) set]; + ns_clip_to_row (w, glyph_row, -1, NO); /* do ns_focus(f, &r, 1); if remove */ + [FRAME_CURSOR_COLOR (f) set]; - if (!active_p) - { - /* inactive window: ignore what we just set and use a hollow box */ - cursorType = hollow_box; - [FRAME_CURSOR_COLOR (f) set]; - } +#ifdef NS_IMPL_COCOA + /* TODO: This makes drawing of cursor plus that of phys_cursor_glyph + atomic. Cleaner ways of doing this should be investigated. + One way would be to set a global variable DRAWING_CURSOR + when making the call to draw_phys..(), don't focus in that + case, then move the ns_unfocus() here after that call. */ + NSDisableScreenUpdates (); +#endif - switch (cursorType) + cursorToDraw = active_p ? cursor_type : HOLLOW_BOX_CURSOR; + switch (cursorToDraw) { - case no_highlight: + case NO_CURSOR: break; - case filled_box: + case FILLED_BOX_CURSOR: NSRectFill (r); - drawGlyph = 1; break; - case hollow_box: + case HOLLOW_BOX_CURSOR: NSRectFill (r); [FRAME_BACKGROUND_COLOR (f) set]; NSRectFill (NSInsetRect (r, 1, 1)); [FRAME_CURSOR_COLOR (f) set]; - drawGlyph = 1; break; - case underscore: + case HBAR_CURSOR: s = r; s.origin.y += lrint (0.75 * s.size.height); + s.size.width = min (FRAME_COLUMN_WIDTH (f), s.size.width); s.size.height = lrint (s.size.height * 0.25); NSRectFill (s); break; - case bar: + case BAR_CURSOR: s = r; - s.size.width = 1; + s.size.width = min (cursor_width, 2); //FIXME(see above) NSRectFill (s); break; } ns_unfocus (f); - /* if needed, draw the character under the cursor */ - if (drawGlyph) + /* draw the character under the cursor */ + if (cursorToDraw != NO_CURSOR) draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); + +#ifdef NS_IMPL_COCOA + NSEnableScreenUpdates (); +#endif + } @@ -2404,6 +2374,8 @@ ns_draw_vertical_window_border (struct window *w, int x, int y0, int y1) struct face *face; NSRect r = NSMakeRect (x, y0, 2, y1-y0); + NSTRACE (ns_draw_vertical_window_border); + face = FACE_FROM_ID (f, VERTICAL_BORDER_FACE_ID); if (face) [ns_lookup_indexed_color(face->foreground, f) set]; @@ -2422,7 +2394,7 @@ show_hourglass (struct atimer *timer) BLOCK_INPUT; - /*PENDING: add NSProgressIndicator to selected frame (see macfns.c) */ + /* TODO: add NSProgressIndicator to selected frame (see macfns.c) */ hourglass_shown_p = 1; UNBLOCK_INPUT; @@ -2435,7 +2407,9 @@ hide_hourglass () if (!hourglass_shown_p) return; - /*PENDING: remove NSProgressIndicator from all frames */ + BLOCK_INPUT; + + /* TODO: remove NSProgressIndicator from all frames */ hourglass_shown_p = 0; UNBLOCK_INPUT; @@ -2451,11 +2425,11 @@ hide_hourglass () static inline NSRect +ns_fix_rect_ibw (NSRect r, int fibw, int frame_pixel_width) /* -------------------------------------------------------------------------- Under NS we draw internal borders inside fringes, and want full-width rendering to go all the way to edge. This function makes that correction. -------------------------------------------------------------------------- */ -ns_fix_rect_ibw (NSRect r, int fibw, int frame_pixel_width) { if (r.origin.y <= fibw+1) { @@ -2563,7 +2537,7 @@ ns_draw_relief (NSRect r, int thickness, char raised_p, if (newBaseCol == nil) newBaseCol = [NSColor grayColor]; - if (newBaseCol != baseCol) /* PENDING: better check */ + if (newBaseCol != baseCol) /* TODO: better check */ { [baseCol release]; baseCol = [newBaseCol retain]; @@ -2843,20 +2817,28 @@ ns_draw_glyph_string (struct glyph_string *s) External (RIF): Main draw-text call. -------------------------------------------------------------------------- */ { - /*PENDING (optimize): focus for box and contents draw */ + /* TODO (optimize): focus for box and contents draw */ NSRect r[2]; int n; char box_drawn_p = 0; NSTRACE (ns_draw_glyph_string); - if (s->next && s->right_overhang && !s->for_overlaps && s->hl != DRAW_CURSOR) + if (s->next && s->right_overhang && !s->for_overlaps/*&&s->hl!=DRAW_CURSOR*/) { - xassert (s->next->img == NULL); - n = ns_get_glyph_string_clip_rect (s->next, r); - ns_focus (s->f, r, n); - ns_maybe_dumpglyphs_background (s->next, 1); - ns_unfocus (s->f); + int width; + struct glyph_string *next; + + for (width = 0, next = s->next; next; + width += next->width, next = next->next) + if (next->first_glyph->type != IMAGE_GLYPH) + { + n = ns_get_glyph_string_clip_rect (s->next, r); + ns_focus (s->f, r, n); + ns_maybe_dumpglyphs_background (s->next, 1); + ns_unfocus (s->f); + next->num_clips = 0; + } } if (!s->for_overlaps && s->face->box != FACE_NO_BOX @@ -2894,11 +2876,11 @@ ns_draw_glyph_string (struct glyph_string *s) - WINDOW_RIGHT_FRINGE_WIDTH (s->w))); r[0].size.width -= overrun; - /* PENDING: Try to work between problem where a stretch glyph on - a partially-visible bottom row will clear part of the - modeline, and another where list-buffers headers and similar - rows erroneously have visible_height set to 0. Not sure - where this is coming from as other terms seem not to show. */ + /* XXX: Try to work between problem where a stretch glyph on + a partially-visible bottom row will clear part of the + modeline, and another where list-buffers headers and similar + rows erroneously have visible_height set to 0. Not sure + where this is coming from as other terms seem not to show. */ r[0].size.height = min (s->height, s->row->visible_height); } @@ -2931,7 +2913,8 @@ ns_draw_glyph_string (struct glyph_string *s) n = ns_get_glyph_string_clip_rect (s, r); ns_focus (s->f, r, n); - if (s->for_overlaps || s->gidx > 0) + if (s->for_overlaps || (s->cmp_from > 0 + && ! s->first_glyph->u.cmp.automatic)) s->background_filled_p = 1; else /* 1 */ ns_maybe_dumpglyphs_background @@ -2942,8 +2925,8 @@ ns_draw_glyph_string (struct glyph_string *s) (s->for_overlaps ? NS_DUMPGLYPH_FOREGROUND : NS_DUMPGLYPH_NORMAL)); ns_tmp_font = (struct nsfont_info *)s->face->font; - if (ns_tmp_font == ~0 || ns_tmp_font == NULL) - ns_tmp_font = FRAME_FONT (s->f); + if (ns_tmp_font == NULL) + ns_tmp_font = (struct nsfont_info *)FRAME_FONT (s->f); ns_tmp_font->font.driver->draw (s, 0, s->nchars, s->x, s->y, @@ -2966,6 +2949,7 @@ ns_draw_glyph_string (struct glyph_string *s) ns_unfocus (s->f); } + s->num_clips = 0; } @@ -3071,14 +3055,15 @@ ns_read_socket (struct terminal *terminal, int expected, /* If have pending open-file requests, attend to the next one of those. */ if (ns_pending_files && [ns_pending_files count] != 0 - && [NSApp openFile: [ns_pending_files objectAtIndex: 0]]) + && [(EmacsApp *)NSApp openFile: [ns_pending_files objectAtIndex: 0]]) { [ns_pending_files removeObjectAtIndex: 0]; } /* Deal with pending service requests. */ else if (ns_pending_service_names && [ns_pending_service_names count] != 0 - && [NSApp fulfillService: [ns_pending_service_names objectAtIndex: 0] - withArg: [ns_pending_service_args objectAtIndex: 0]]) + && [(EmacsApp *) + NSApp fulfillService: [ns_pending_service_names objectAtIndex: 0] + withArg: [ns_pending_service_args objectAtIndex: 0]]) { [ns_pending_service_names removeObjectAtIndex: 0]; [ns_pending_service_args removeObjectAtIndex: 0]; @@ -3089,7 +3074,7 @@ ns_read_socket (struct terminal *terminal, int expected, to ourself, otherwise [NXApp run] will never exit. */ send_appdefined = YES; - /*PENDING: from termhooks.h: */ + /* TODO: from termhooks.h: */ /* XXX Please note that a non-zero value of EXPECTED only means that there is available input on at least one of the currently opened terminal devices -- but not necessarily on this device. @@ -3174,35 +3159,6 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds, repeats: YES] retain]; - if (!NILP (ns_cursor_blink_mode) && !cursor_blink_entry) - { - if (!NUMBERP (ns_cursor_blink_rate)) - ns_cursor_blink_rate = make_float (0.5); - cursor_blink_entry = [[NSTimer - scheduledTimerWithTimeInterval: XFLOATINT (ns_cursor_blink_rate) - target: NSApp - selector: @selector (cursor_blink_handler:) - userInfo: 0 - repeats: YES] - retain]; - } - else if (NILP (ns_cursor_blink_mode) && cursor_blink_entry) - { - if (NUMBERP (ns_cursor_blink_rate)) - ns_cursor_blink_rate = Qnil; - struct ns_display_info *dpyinfo = x_display_list; /* HACK */ - [cursor_blink_entry invalidate]; - [cursor_blink_entry release]; - cursor_blink_entry = 0; - if (dpyinfo->x_highlight_frame) - { - Lisp_Object tem - = get_frame_param (dpyinfo->x_highlight_frame, Qcursor_type); - dpyinfo->x_highlight_frame->output_data.ns->desired_cursor - = ns_lisp_to_cursor_type (tem); - } - } - /* Let Application dispatch events until it receives an event of the type NX_APPDEFINED, which should only be sent by timeout_handler. */ inNsSelect = 1; @@ -3436,7 +3392,24 @@ x_wm_set_icon_position (struct frame *f, int icon_x, int icon_y) ========================================================================== */ -static Lisp_Object ns_string_to_lispmod (char *s) +int +x_display_pixel_height (dpyinfo) + struct ns_display_info *dpyinfo; +{ + NSScreen *screen = [NSScreen mainScreen]; + return [screen frame].size.height; +} + +int +x_display_pixel_width (dpyinfo) + struct ns_display_info *dpyinfo; +{ + NSScreen *screen = [NSScreen mainScreen]; + return [screen frame].size.width; +} + + +static Lisp_Object ns_string_to_lispmod (const char *s) /* -------------------------------------------------------------------------- Convert modifier name to lisp symbol -------------------------------------------------------------------------- */ @@ -3488,8 +3461,6 @@ ns_set_default_prefs () ns_command_modifier = Qsuper; ns_control_modifier = Qcontrol; ns_function_modifier = Qnone; - ns_cursor_blink_rate = Qnil; - ns_cursor_blink_mode = Qnil; ns_expand_space = make_float (0.0); ns_antialias_text = Qt; ns_antialias_threshold = 10.0; /* not exposed to lisp side */ @@ -3537,8 +3508,6 @@ ns_initialize_display_info (struct ns_display_info *dpyinfo) NSScreen *screen = [NSScreen mainScreen]; NSWindowDepth depth = [screen depth]; - dpyinfo->width = [screen frame].size.width; - dpyinfo->height = [screen frame].size.height; dpyinfo->resx = 72.27; /* used 75.0, but this makes pt == pixel, expected */ dpyinfo->resy = 72.27; dpyinfo->color_p = ![NSDeviceWhiteColorSpace isEqualToString: @@ -3596,7 +3565,7 @@ static struct redisplay_interface ns_redisplay_interface = x_get_glyph_overhangs, /*23: generic OK */ x_fix_overlapping_area, /*generic OK */ ns_draw_fringe_bitmap, /*23 */ - 0, /* define_fringe_bitmap */ /*PENDING: simplify ns_draw_fringe_bitmap? */ + 0, /* define_fringe_bitmap */ /* FIXME: simplify ns_draw_fringe_bitmap */ 0, /* destroy_fringe_bitmap */ ns_compute_glyph_string_overhangs, /*23 */ ns_draw_glyph_string, /*23: interface to nsfont.m */ @@ -3611,7 +3580,7 @@ static struct redisplay_interface ns_redisplay_interface = static void ns_delete_display (struct ns_display_info *dpyinfo) { - /*PENDING... */ + /* TODO... */ } @@ -3717,7 +3686,7 @@ ns_term_init (Lisp_Object display_name) /* count object allocs (About, click icon); on OS X use ObjectAlloc tool */ /*GSDebugAllocationActive (YES); */ BLOCK_INPUT; -handling_signal = 0; + handling_signal = 0; if (!ns_initialized) { @@ -3796,10 +3765,6 @@ handling_signal = 0; Qnil, Qnil, NO, YES); if (NILP (ns_function_modifier)) ns_function_modifier = Qnone; - ns_default ("CursorBlinkRate", &ns_cursor_blink_rate, - make_float (0.5), Qnil, YES, NO); - if (NUMBERP (ns_cursor_blink_rate)) - ns_cursor_blink_mode = Qt; ns_default ("ExpandSpace", &ns_expand_space, make_float (0.5), make_float (0.0), YES, NO); ns_default ("GSFontAntiAlias", &ns_antialias_text, @@ -3823,37 +3788,37 @@ handling_signal = 0; ns_selection_color = NS_SELECTION_COLOR_DEFAULT; { - id cl; - Lisp_Object tem, tem1; - extern Lisp_Object Vsource_directory; - - cl = [NSColorList colorListNamed: @"Emacs"]; + NSColorList *cl = [NSColorList colorListNamed: @"Emacs"]; if ( cl == nil ) { - /* first try data_dir, then invocation-dir - and finally source-directory/etc */ - tem1 = tem - = Fexpand_file_name (build_string ("Emacs.clr"), Vdata_directory); - if (NILP (Ffile_exists_p (tem))) + Lisp_Object color_file, color_map, color; + int r,g,b; + unsigned long c; + char *name; + + color_file = Fexpand_file_name (build_string ("rgb.txt"), + Fsymbol_value (intern ("data-directory"))); + if (NILP (Ffile_readable_p (color_file))) + fatal ("Could not find %s.\n", SDATA (color_file)); + + color_map = Fx_load_color_file (color_file); + if (NILP (color_map)) + fatal ("Could not read %s.\n", SDATA (color_file)); + + cl = [[NSColorList alloc] initWithName: @"Emacs"]; + for ( ; CONSP (color_map); color_map = XCDR (color_map)) { - tem = Fexpand_file_name (build_string ("Emacs.clr"), - Vinvocation_directory); - if (NILP (Ffile_exists_p (tem))) - { - Lisp_Object newdir - = Fexpand_file_name (build_string ("etc/"), - Vsource_directory); - tem = Fexpand_file_name (build_string ("Emacs.clr"), - newdir); - } + color = XCAR (color_map); + name = SDATA (XCAR (color)); + c = XINT (XCDR (color)); + [cl setColor: + [NSColor colorWithCalibratedRed: RED_FROM_ULONG (c) / 255.0 + green: GREEN_FROM_ULONG (c) / 255.0 + blue: BLUE_FROM_ULONG (c) / 255.0 + alpha: 1.0] + forKey: [NSString stringWithUTF8String: name]]; } - - cl = [[NSColorList alloc] - initWithName: @"Emacs" - fromFile: [NSString stringWithCString: SDATA (tem)]]; - if (cl ==nil) - fatal ("Could not find %s.\n", SDATA (tem1)); [cl writeToFile: nil]; } } @@ -3875,13 +3840,14 @@ handling_signal = 0; #ifdef NS_IMPL_COCOA { NSMenu *appMenu; - id item; + NSMenuItem *item; /* set up the application menu */ svcsMenu = [[EmacsMenu alloc] initWithTitle: @"Services"]; [svcsMenu setAutoenablesItems: NO]; appMenu = [[EmacsMenu alloc] initWithTitle: @"Emacs"]; [appMenu setAutoenablesItems: NO]; mainMenu = [[EmacsMenu alloc] initWithTitle: @""]; + dockMenu = [[EmacsMenu alloc] initWithTitle: @""]; [appMenu insertItemWithTitle: @"About Emacs" action: @selector (orderFrontStandardAboutPanel:) @@ -3920,6 +3886,10 @@ handling_signal = 0; keyEquivalent: @"" atIndex: 0]; [mainMenu setSubmenu: appMenu forItem: item]; + [dockMenu insertItemWithTitle: @"New Frame" + action: @selector (newFrame:) + keyEquivalent: @"" + atIndex: 0]; [NSApp setMainMenu: mainMenu]; [NSApp setAppleMenu: appMenu]; @@ -3948,152 +3918,6 @@ ns_term_shutdown (int sig) } -void -syms_of_nsterm () -{ - NSTRACE (syms_of_nsterm); - DEFVAR_LISP ("ns-input-file", &ns_input_file, - "The file specified in the last NS event."); - ns_input_file =Qnil; - - DEFVAR_LISP ("ns-input-text", &ns_input_text, - "The data received in the last NS text drag event."); - ns_input_text =Qnil; - - DEFVAR_LISP ("ns-working-text", &ns_working_text, - "String for visualizing working composition sequence."); - ns_working_text =Qnil; - - DEFVAR_LISP ("ns-input-font", &ns_input_font, - "The font specified in the last NS event."); - ns_input_font =Qnil; - - DEFVAR_LISP ("ns-input-fontsize", &ns_input_fontsize, - "The fontsize specified in the last NS event."); - ns_input_fontsize =Qnil; - - DEFVAR_LISP ("ns-input-line", &ns_input_line, - "The line specified in the last NS event."); - ns_input_line =Qnil; - - DEFVAR_LISP ("ns-input-color", &ns_input_color, - "The color specified in the last NS event."); - ns_input_color =Qnil; - - DEFVAR_LISP ("ns-input-spi-name", &ns_input_spi_name, - "The service name specified in the last NS event."); - ns_input_spi_name =Qnil; - - DEFVAR_LISP ("ns-input-spi-arg", &ns_input_spi_arg, - "The service argument specified in the last NS event."); - ns_input_spi_arg =Qnil; - - DEFVAR_LISP ("ns-alternate-modifier", &ns_alternate_modifier, - "This variable describes the behavior of the alternate or option key.\n\ -Set to control, meta, alt, super, or hyper means it is taken to be that key.\n\ -Set to none means that the alternate / option key is not interpreted by Emacs\n\ -at all, allowing it to be used at a lower level for accented character entry."); - - DEFVAR_LISP ("ns-command-modifier", &ns_command_modifier, - "This variable describes the behavior of the command key.\n\ -Set to control, meta, alt, super, or hyper means it is taken to be that key."); - - DEFVAR_LISP ("ns-control-modifier", &ns_control_modifier, - "This variable describes the behavior of the control key.\n\ -Set to control, meta, alt, super, or hyper means it is taken to be that key."); - - DEFVAR_LISP ("ns-function-modifier", &ns_function_modifier, - "This variable describes the behavior of the function key (on laptops).\n\ -Set to control, meta, alt, super, or hyper means it is taken to be that key.\n\ -Set to none means that the function key is not interpreted by Emacs at all,\n\ -allowing it to be used at a lower level for accented character entry."); - - DEFVAR_LISP ("ns-cursor-blink-rate", &ns_cursor_blink_rate, - "Rate at which the Emacs cursor blinks (in seconds).\n\ -Set to nil to disable blinking."); - - DEFVAR_LISP ("ns-cursor-blink-mode", &ns_cursor_blink_mode, - "Internal variable -- use M-x blink-cursor-mode or preferences\n\ -panel to control this setting."); - - DEFVAR_LISP ("ns-expand-space", &ns_expand_space, - "Amount by which spacing between lines is expanded (positive)\n\ -or shrunk (negative). Zero (the default) means standard line height.\n\ -(This variable should only be read, never set.)"); - - DEFVAR_LISP ("ns-antialias-text", &ns_antialias_text, - "Non-nil (the default) means to render text antialiased. Only has an effect on OS X Panther and above."); - - DEFVAR_LISP ("ns-use-qd-smoothing", &ns_use_qd_smoothing, - "Whether to render text using QuickDraw (less heavy) antialiasing. Only has an effect on OS X Panther and above. Default is nil (use Quartz smoothing)."); - - DEFVAR_LISP ("ns-use-system-highlight-color", - &ns_use_system_highlight_color, - "Whether to use the system default (on OS X only) for the highlight color. Nil means to use standard emacs (prior to version 21) 'grey'."); - - staticpro (&ns_display_name_list); - ns_display_name_list = Qnil; - - staticpro (&last_mouse_motion_frame); - last_mouse_motion_frame = Qnil; - -/*23: now apparently we need to tell emacs what modifiers there are.. */ - Qmodifier_value = intern ("modifier-value"); - Qalt = intern ("alt"); - Fput (Qalt, Qmodifier_value, make_number (alt_modifier)); - Qhyper = intern ("hyper"); - Fput (Qhyper, Qmodifier_value, make_number (hyper_modifier)); - Qmeta = intern ("meta"); - Fput (Qmeta, Qmodifier_value, make_number (meta_modifier)); - Qsuper = intern ("super"); - Fput (Qsuper, Qmodifier_value, make_number (super_modifier)); - Qcontrol = intern ("control"); - Fput (Qcontrol, Qmodifier_value, make_number (ctrl_modifier)); - - /*PENDING: move to common code */ - DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars, - doc: /* If not nil, Emacs uses toolkit scroll bars. */); -#ifdef USE_TOOLKIT_SCROLL_BARS - Vx_toolkit_scroll_bars = Qt; -#else - Vx_toolkit_scroll_bars = Qnil; -#endif - - /* these are unsupported but we need the declarations to avoid whining - messages from cus-start.el */ - DEFVAR_BOOL ("x-use-underline-position-properties", - &x_use_underline_position_properties, - doc: /* NOT SUPPORTED UNDER NS. -*Non-nil means make use of UNDERLINE_POSITION font properties. -A value of nil means ignore them. If you encounter fonts with bogus -UNDERLINE_POSITION font properties, for example 7x13 on XFree prior -to 4.1, set this to nil. - -NOTE: Not supported on Mac yet. */); - x_use_underline_position_properties = 0; - - DEFVAR_BOOL ("x-underline-at-descent-line", - &x_underline_at_descent_line, - doc: /* NOT SUPPORTED UNDER NS. -*Non-nil means to draw the underline at the same place as the descent line. -A value of nil means to draw the underline according to the value of the -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-windowing"), Qnil); - /* PENDING: try to move this back into lisp, ns-win.el loaded too late - right now */ - { - Lisp_Object args[3] = { intern ("ns-version-string"), build_string ("9.0"), - build_string ("NS Window system port version number.") }; - Fdefconst (Flist (3, args)); - } -} - - - /* ========================================================================== EmacsApp implementation @@ -4174,6 +3998,40 @@ baseline level. The default value is nil. */); } +- (void)newFrame: (id)sender +{ + struct frame *emacsframe = SELECTED_FRAME (); + NSEvent *theEvent = [NSApp currentEvent]; + + if (!emacs_event) + return; + emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT; + emacs_event->code = KEY_NS_NEW_FRAME; + emacs_event->modifiers = 0; + EV_TRAILER (theEvent); +} + + +/* Open a file (used by below, after going into queue read by ns_read_socket) */ +- (BOOL) openFile: (NSString *)fileName +{ + struct frame *emacsframe = SELECTED_FRAME (); + NSEvent *theEvent = [NSApp currentEvent]; + + if (!emacs_event) + return NO; + + emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT; + emacs_event->code = KEY_NS_OPEN_FILE_LINE; + ns_input_file = append2 (ns_input_file, build_string ([fileName UTF8String])); + ns_input_line = Qnil; /* can be start or cons start,end */ + emacs_event->modifiers =0; + EV_TRAILER (theEvent); + + return YES; +} + + /* ************************************************************************** EmacsApp delegate implementation @@ -4215,7 +4073,7 @@ baseline level. The default value is nil. */); Fcons (build_string ("Cancel"), Qnil), Fcons (build_string ("Save and Exit"), Qt)); Lisp_Object res = ns_popup_dialog (Qt, contents, Qnil); -fprintf (stderr, "res = %d\n", EQ (res, Qt)); // FIXME +fprintf (stderr, "res = %d\n", EQ (res, Qt)); /* FIXME */ if (EQ (res, Qt)) { Feval (Fcons (intern ("save-buffers-kill-emacs"), Qnil)); @@ -4225,26 +4083,6 @@ fprintf (stderr, "res = %d\n", EQ (res, Qt)); // FIXME } -/* Open a file (used by below, after going into queue read by ns_read_socket) */ --(BOOL) openFile: (NSString *)fileName -{ - struct frame *emacsframe = SELECTED_FRAME (); - NSEvent *theEvent = [NSApp currentEvent]; - - if (!emacs_event) - return NO; - - emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT; - emacs_event->code = KEY_NS_OPEN_FILE_LINE; - ns_input_file = append2 (ns_input_file, build_string ([fileName UTF8String])); - ns_input_line = Qnil; /* can be start or cons start,end */ - emacs_event->modifiers =0; - EV_TRAILER (theEvent); - - return YES; -} - - /* Notification from the Workspace to open a file */ - (BOOL)application: sender openFile: (NSString *)file { @@ -4276,10 +4114,24 @@ fprintf (stderr, "res = %d\n", EQ (res, Qt)); // FIXME NSString *file; while ((file = [files nextObject]) != nil) [ns_pending_files addObject: file]; - return YES; + +/* TODO: when GNUstep implements this (and we require that version of + GNUstep), remove. */ +#ifndef NS_IMPL_GNUSTEP + [self replyToOpenOrPrint: NSApplicationDelegateReplySuccess]; +#endif /* !NS_IMPL_GNUSTEP */ + } -/*PENDING: these may help w/IO switching btwn terminal and NSApp */ + +/* Handle dock menu requests. */ +- (NSMenu *)applicationDockMenu: (NSApplication *) sender +{ + return dockMenu; +} + + +/* TODO: these may help w/IO switching btwn terminal and NSApp */ - (void)applicationDidBecomeActive: (NSNotification *)notification { } @@ -4308,31 +4160,6 @@ fprintf (stderr, "res = %d\n", EQ (res, Qt)); // FIXME extern void update_window_cursor (struct window *w, int on); -- (void)cursor_blink_handler: (NSTimer *)cursorEntry -/* -------------------------------------------------------------------------- - Flash the cursor - -------------------------------------------------------------------------- */ -{ - struct ns_display_info *dpyinfo = x_display_list; /*HACK, but OK for now */ - struct frame *f = dpyinfo->x_highlight_frame; - NSTRACE (cursor_blink_handler); - - if (!f) - return; - if (f->output_data.ns->current_cursor == no_highlight) - { - Lisp_Object tem = get_frame_param (f, Qcursor_type); - f->output_data.ns->desired_cursor = ns_lisp_to_cursor_type (tem); - } - else - { - f->output_data.ns->desired_cursor = no_highlight; - } - update_window_cursor (XWINDOW (FRAME_SELECTED_WINDOW (f)), 1); - /*x_update_cursor (f, 1); */ -} - - - (void)fd_handler: (NSTimer *) fdEntry /* -------------------------------------------------------------------------- Check data waiting on file descriptors and terminate if so @@ -4438,6 +4265,8 @@ extern void update_window_cursor (struct window *w, int on); if (newFont = [sender convertFont: ((struct nsfont_info *)face->font)->nsfont]) { + SET_FRAME_GARBAGED (emacsframe); /* now needed as of 2008/10 */ + emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT; emacs_event->modifiers = 0; emacs_event->code = KEY_NS_CHANGE_FONT; @@ -4494,21 +4323,19 @@ extern void update_window_cursor (struct window *w, int on); if (!emacs_event) return; -/*#if defined (COCOA_EXPERIMENTAL_CTRL_G) */ if (![[self window] isKeyWindow]) { - /* PENDING: Using NO_SOCK_SIGIO like Carbon causes a condition in which, - when Emacs display updates a different frame from the current one, - and temporarily selects it, then processes some interrupt-driven - input (dispnew.c:3878), OS will send the event to the correct NSWindow, - but for some reason that window has its first responder set to the - NSView most recently updated (I guess), which is not the correct one. - UPDATE: After multi-TTY merge this happens even w/o NO_SOCK_SIGIO */ + /* XXX: Using NO_SOCK_SIGIO like Carbon causes a condition in which, + when Emacs display updates a different frame from the current one, + and temporarily selects it, then processes some interrupt-driven + input (dispnew.c:3878), OS will send the event to the correct NSWindow, + but for some reason that window has its first responder set to the + NSView most recently updated (I guess), which is not the correct one. + UPDATE: After multi-TTY merge this happens even w/o NO_SOCK_SIGIO */ if ([[theEvent window] isKindOfClass: [EmacsWindow class]]) - [[(EmacsView *)[theEvent window] delegate] keyDown: theEvent]; + [(EmacsView *)[[theEvent window] delegate] keyDown: theEvent]; return; } -/*#endif */ if (nsEvArray == nil) nsEvArray = [[NSMutableArray alloc] initWithCapacity: 1]; @@ -4558,7 +4385,7 @@ extern void update_window_cursor (struct window *w, int on); && !fnKeysym && [[theEvent characters] length] != 0) { - /* PENDING: the code we get will be unshifted, so if we have + /* XXX: the code we get will be unshifted, so if we have a shift modifier, must convert ourselves */ if (!(flags & NSShiftKeyMask)) code = [[theEvent characters] characterAtIndex: 0]; @@ -4667,7 +4494,7 @@ if (NS_KEYLOG) NSLog (@"insertText '%@'\tlen = %d", aString, len); for (i =0; imodifiers = 0; @@ -4785,12 +4612,12 @@ if (NS_KEYLOG) NSLog (@"firstRectForCharRange request"); return rect; } -- (long)conversationIdentifier +- (NSInteger)conversationIdentifier { - return (long)self; + return (NSInteger)self; } -/*PENDING: below here not yet implemented correctly, but may not be needed */ +/* TODO: below here not yet implemented correctly, but may not be needed */ - (void)doCommandBySelector: (SEL)aSelector { @@ -4917,7 +4744,7 @@ if (NS_KEYLOG) NSLog (@"attributedSubstringFromRange request"); struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe); Lisp_Object frame; - NSTRACE (mouseMoved); +// NSTRACE (mouseMoved); last_mouse_movement_time = EV_TIMESTAMP (e); last_mouse_motion_position @@ -4978,8 +4805,6 @@ if (NS_KEYLOG) NSLog (@"attributedSubstringFromRange request"); NSTRACE (windowShouldClose); windowClosing = YES; - if (ns_window_num <= 1) - return NO; if (!emacs_event) return NO; emacs_event->kind = DELETE_WINDOW_EVENT; @@ -5086,13 +4911,19 @@ if (NS_KEYLOG) NSLog (@"attributedSubstringFromRange request"); x_set_window_size (emacsframe, 0, cols, rows); ns_send_appdefined (-1); + + /* The following line causes a crash on GNUstep. Adrian Robert + says he doesn't remember why he added this line, but removing it + doesn't seem to cause problems on OSX, either. */ +#if 0 [NSApp stopModal]; +#endif } - (void)windowDidBecomeKey: (NSNotification *)notification +/* cf. x_detect_focus_change(), x_focus_changed(), x_new_focus_frame() */ { - int val = ns_lisp_to_cursor_type (get_frame_param (emacsframe, Qcursor_type)); struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe); struct frame *old_focus = dpyinfo->x_focus_frame; @@ -5100,13 +4931,6 @@ if (NS_KEYLOG) NSLog (@"attributedSubstringFromRange request"); if (emacsframe != old_focus) dpyinfo->x_focus_frame = emacsframe; - /*/last_mouse_frame = emacsframe;? */ - - if (val >= 0) - { - FRAME_NEW_CURSOR (emacsframe) = val; -/* x_update_cursor (emacsframe, 1); // will happen in ns_frame_rehighlight */ - } ns_frame_rehighlight (emacsframe); @@ -5119,27 +4943,20 @@ if (NS_KEYLOG) NSLog (@"attributedSubstringFromRange request"); - (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); NSTRACE (windowDidResignKey); - if (!windowClosing && [[self window] isVisible] == YES) - { - FRAME_NEW_CURSOR (emacsframe) = hollow_box; - x_update_cursor (emacsframe, 1); - FRAME_LAST_INACTIVE (emacsframe) = YES; - } - - if (dpyinfo->x_highlight_frame == emacsframe) - dpyinfo->x_highlight_frame = 0; if (dpyinfo->x_focus_frame == emacsframe) dpyinfo->x_focus_frame = 0; - if (dpyinfo->mouse_face_mouse_frame == emacsframe) - { - clear_mouse_face (dpyinfo); - dpyinfo->mouse_face_mouse_frame = 0; - } + ns_frame_rehighlight (emacsframe); + + /* FIXME: for some reason needed on second and subsequent clicks away + from sole-frame Emacs to get hollow box to show */ + if (!windowClosing && [[self window] isVisible] == YES) + x_update_cursor (emacsframe, 1); if (emacs_event) { @@ -5386,7 +5203,8 @@ if (NS_KEYLOG) NSLog (@"attributedSubstringFromRange request"); context_menu_value = [sender tag]; else find_and_call_menu_selection (emacsframe, emacsframe->menu_bar_items_used, - emacsframe->menu_bar_vector, [sender tag]); + emacsframe->menu_bar_vector, + (void *)[sender tag]); ns_send_appdefined (-1); return self; } @@ -5725,8 +5543,8 @@ if (NS_KEYLOG) NSLog (@"attributedSubstringFromRange request"); + (float) scrollerWidth { - /* PENDING: if we want to allow variable widths, this is the place to do it, - however neither GNUstep nor Cocoa support it very well */ + /* TODO: if we want to allow variable widths, this is the place to do it, + however neither GNUstep nor Cocoa support it very well */ return [NSScroller scrollerWidth]; } @@ -5869,8 +5687,8 @@ if (NS_KEYLOG) NSLog (@"attributedSubstringFromRange request"); return self; } -/* PENDING: unused at moment (see ns_mouse_position) at the moment because - drag events will go directly to the EmacsScroller. Leaving in for now. */ +/* FIXME: unused at moment (see ns_mouse_position) at the moment because + drag events will go directly to the EmacsScroller. Leaving in for now. */ -(void)getMouseMotionPart: (int *)part window: (Lisp_Object *)window x: (Lisp_Object *)x y: ( Lisp_Object *)y { @@ -6136,18 +5954,15 @@ static void selectItemWithTag (NSPopUpButton *popup, int tag) int cursorType = ns_lisp_to_cursor_type (get_frame_param (frame, Qcursor_type)); prevExpandSpace = XFLOATINT (ns_expand_space); - prevBlinkRate = NILP (ns_cursor_blink_rate) - ? 0 : XFLOATINT (ns_cursor_blink_rate); #ifdef NS_IMPL_COCOA prevUseHighlightColor = ns_use_system_highlight_color; #endif [expandSpaceSlider setFloatValue: prevExpandSpace]; - [cursorBlinkSlider setFloatValue: prevBlinkRate]; - [cursorTypeMatrix selectCellWithTag: (cursorType == filled_box ? 1 : - (cursorType == bar ? 2 : - (cursorType == underscore ? 3 : 4)))]; + [cursorTypeMatrix selectCellWithTag: (cursorType == FILLED_BOX_CURSOR ? 1 : + (cursorType == BAR_CURSOR ? 2 : + (cursorType == HBAR_CURSOR ? 3 : 4)))]; selectItemWithTag (alternateModMenu, parse_solitary_modifier (ns_alternate_modifier)); selectItemWithTag (commandModMenu, @@ -6166,64 +5981,32 @@ static void selectItemWithTag (NSPopUpButton *popup, int tag) - (void) setValuesFromPanel { - int cursorTag = [[cursorTypeMatrix selectedCell] tag]; int altTag = [[alternateModMenu selectedItem] tag]; int cmdTag = [[commandModMenu selectedItem] tag]; #ifdef NS_IMPL_COCOA int ctrlTag = [[controlModMenu selectedItem] tag]; int fnTag = [[functionModMenu selectedItem] tag]; #endif - float blinkRate = [cursorBlinkSlider floatValue]; float expandSpace = [expandSpaceSlider floatValue]; - Lisp_Object old_cursor_blink_mode; + int cursorTag = [[cursorTypeMatrix selectedCell] tag]; + Lisp_Object cursor_type = ns_cursor_type_to_lisp + ( cursorTag == 1 ? FILLED_BOX_CURSOR + : cursorTag == 2 ? BAR_CURSOR + : cursorTag == 3 ? HBAR_CURSOR : HOLLOW_BOX_CURSOR); if (expandSpace != prevExpandSpace) { ns_expand_space = make_float (expandSpace); - /* PENDING: more needed: store needed metrics in nsfont_info, update + /* TODO: more needed: store needed metrics in nsfont_info, update frame default font max_bounds and fontp, recompute faces */ /* FRAME_LINE_HEIGHT (frame) *= (expandSpace / prevExpandSpace); x_set_window_size (frame, 0, frame->text_cols, frame->text_lines); */ prevExpandSpace = expandSpace; } - if (blinkRate != prevBlinkRate) - { - old_cursor_blink_mode = ns_cursor_blink_mode; - if (blinkRate == 0.0) - { - ns_cursor_blink_rate = Qnil; - ns_cursor_blink_mode = Qnil; - } - else - { - ns_cursor_blink_rate = make_float (blinkRate); - ns_cursor_blink_mode = Qt; - } - if (!EQ (ns_cursor_blink_mode, old_cursor_blink_mode)) - Feval (Fcons (intern ("blink-cursor-mode"), Qnil)); - - if (blinkRate != 0.0 && prevBlinkRate != 0.0) - { /* if changed rates, remove blink handler so change picked up */ - struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (frame); - [cursor_blink_entry invalidate]; - [cursor_blink_entry release]; - cursor_blink_entry = 0; - if (dpyinfo->x_highlight_frame) - { - Lisp_Object tem - = get_frame_param (dpyinfo->x_highlight_frame, Qcursor_type); - dpyinfo->x_highlight_frame->output_data.ns->desired_cursor - = ns_lisp_to_cursor_type (tem); - } - } - prevBlinkRate = blinkRate; - } - FRAME_NEW_CURSOR (frame) - = (cursorTag == 1 ? filled_box - : cursorTag == 2 ? bar - : cursorTag == 3 ? underscore : hollow_box); - store_frame_param (frame, Qcursor_type, - ns_cursor_type_to_lisp (FRAME_NEW_CURSOR (frame))); + + store_frame_param (frame, Qcursor_type, cursor_type); + ns_set_cursor_type(frame, cursor_type, Qnil); /* FIXME: do only if changed */ + ns_alternate_modifier = ns_mod_to_lisp (altTag); ns_command_modifier = ns_mod_to_lisp (cmdTag); #ifdef NS_IMPL_COCOA @@ -6303,6 +6086,7 @@ static void selectItemWithTag (NSPopUpButton *popup, int tag) /* ========================================================================== Font-related functions; these used to be in nsfaces.m + The XLFD functions (115 lines) are an abomination that should be removed. ========================================================================== */ @@ -6351,141 +6135,9 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset) } -Lisp_Object -ns_list_fonts (FRAME_PTR f, Lisp_Object pattern, int size, int maxnames) -/* -------------------------------------------------------------------------- - This is used by the xfaces system. It is expected to speak XLFD. - -------------------------------------------------------------------------- */ -{ - Lisp_Object list = Qnil, - rpattern, - key, - tem, - args[2]; - struct re_pattern_buffer *bufp; - id fm = [NSFontManager sharedFontManager]; - NSEnumerator *fenum, *senum; - NSArray *membInfo; - NSString *fontname; - const char *xlfdName; - char *pattFam; - char *patt; - NSString *famName; - - NSTRACE (ns_list_fonts); - - CHECK_STRING (pattern); - patt = SDATA (pattern); - -#if 0 -/* temporary: for font_backend, we use fontsets, and when these are defined, - the old XLFD-based system is used; eventually this will be replaced by - backend code, but for now we allow specs that are just family names */ - /* if pattern is not XLFD, panic now */ - if (patt[0] != '-') - error ("ns_list_fonts: X font name (XLFD) expected."); - - /* if unicode encoding not requested, also die */ - if (!strstr (patt, "iso10646") && patt[strlen (patt)-3] != '*') - return Qnil; -#endif /* 0 */ - - key = f ? Fcons (pattern, make_number (maxnames)) : Qnil; - tem = f ? XCDR (FRAME_NS_DISPLAY_INFO (f)->name_list_element) : Qnil; - - /* See if we cached the result for this particular query. - The cache is an alist of the form: - ((((PATTERN . MAXNAMES) FONTNAME) ...) ...) - */ - if (f && !NILP (list = Fassoc (key, tem))) - { - list = Fcdr_safe (list); - /* We have a cached list. Don't have to get the list again. */ - if (!NILP (list)) - return list; - } - - if (patt[0] != '-') - pattFam = patt; - else - pattFam = ns_xlfd_to_fontname (patt); - /*PENDING: '*' at beginning matches literally.. */ - if (pattFam[0] == '*') - pattFam[0] = '.'; - - /* must start w/family name, but can have other stuff afterwards - (usually bold and italic specifiers) */ - args[0] = build_string ("^"); - args[1] = build_string (pattFam); - rpattern = Fconcat (2, args); - bufp = compile_pattern (rpattern, 0, Vascii_canon_table, 0, 0); - - list = Qnil; - fenum = [[fm availableFontFamilies] objectEnumerator]; - while ( (famName = [fenum nextObject]) ) - { - NSMutableString *tmp = [famName mutableCopy]; - const char *fname; - NSRange r; - - /* remove spaces, to look like postscript name */ - while ((r = [tmp rangeOfString: @" "]).location != NSNotFound) - [tmp deleteCharactersInRange: r]; - - fname = [tmp UTF8String]; - int len = strlen (fname); - BOOL foundItal; - const char *synthItalFont; - - if (re_search (bufp, fname, len, 0, len, 0) >= 0) - { - /* Found a family. Add all variants. If we have no italic variant, - add a synthItal. */ - senum =[[fm availableMembersOfFontFamily: famName] objectEnumerator]; - foundItal = NO; - synthItalFont = NULL; - while (membInfo = [senum nextObject]) - { - xlfdName - = ns_fontname_to_xlfd ([[membInfo objectAtIndex: 0] - UTF8String]); - list = Fcons (build_string (xlfdName), list); - if (!synthItalFont) - { - NSString *synthName - = [[membInfo objectAtIndex: 0] - stringByAppendingString: @"-synthItal"]; - synthItalFont = [synthName UTF8String]; - } - else if ([[membInfo objectAtIndex: 3] intValue] - & NSItalicFontMask) - foundItal = YES; - } - if (foundItal == NO) - { - xlfdName = ns_fontname_to_xlfd (synthItalFont); - list = Fcons (build_string (xlfdName), list); - } - } - [tmp release]; - } - - /* fallback */ - if (XFASTINT (Flength (list)) == 0) - list = Fcons (build_string (ns_fontname_to_xlfd ("Monaco")), list); - - /* store result in cache */ - if (f != NULL) - XCDR_AS_LVALUE (FRAME_NS_DISPLAY_INFO (f)->name_list_element) - = Fcons (Fcons (key, list), - XCDR (FRAME_NS_DISPLAY_INFO (f)->name_list_element)); - return list; -} - - /* XLFD: -foundry-family-weight-slant-swidth-adstyle-pxlsz-ptSz-resx-resy-spc-avgWidth-rgstry-encoding */ -const char * +static const char * ns_font_to_xlfd (NSFont *nsfont) /* -------------------------------------------------------------------------- Convert an NS font name to an X font name (XLFD). @@ -6494,7 +6146,7 @@ ns_font_to_xlfd (NSFont *nsfont) { NSFontManager *mgr = [NSFontManager sharedFontManager]; NSString *sname = [nsfont /*familyName*/fontName]; - char *famName = [sname UTF8String]; + char *famName = (char *)[sname UTF8String]; char *weightStr = [mgr fontNamed: sname hasTraits: NSBoldFontMask] ? "bold" : "medium"; char *slantStr = [mgr fontNamed: sname hasTraits: NSItalicFontMask] ? @@ -6505,7 +6157,7 @@ ns_font_to_xlfd (NSFont *nsfont) int i, len; /* change '-' to '$' to avoid messing w/XLFD separator */ - for (len =strlen (famName), i =0; i