aboutsummaryrefslogtreecommitdiffstats
path: root/src/nsterm.m
diff options
context:
space:
mode:
Diffstat (limited to 'src/nsterm.m')
-rw-r--r--src/nsterm.m254
1 files changed, 181 insertions, 73 deletions
diff --git a/src/nsterm.m b/src/nsterm.m
index 247ef4dd40c..78d690c020d 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -158,10 +158,20 @@ Lisp_Object ns_right_alternate_modifier;
158Lisp_Object ns_command_modifier; 158Lisp_Object ns_command_modifier;
159 159
160/* Specifies which emacs modifier should be generated when NS receives 160/* Specifies which emacs modifier should be generated when NS receives
161 the right Command modifier. Has same values as ns_command_modifier plus
162 the value Qleft which means whatever value ns_command_modifier has. */
163Lisp_Object ns_right_command_modifier;
164
165/* Specifies which emacs modifier should be generated when NS receives
161 the Control modifier. May be any of the modifier lisp symbols. */ 166 the Control modifier. May be any of the modifier lisp symbols. */
162Lisp_Object ns_control_modifier; 167Lisp_Object ns_control_modifier;
163 168
164/* Specifies which emacs modifier should be generated when NS receives 169/* Specifies which emacs modifier should be generated when NS receives
170 the right Control modifier. Has same values as ns_control_modifier plus
171 the value Qleft which means whatever value ns_control_modifier has. */
172Lisp_Object ns_right_control_modifier;
173
174/* Specifies which emacs modifier should be generated when NS receives
165 the Function modifier (laptops). May be any of the modifier lisp symbols. */ 175 the Function modifier (laptops). May be any of the modifier lisp symbols. */
166Lisp_Object ns_function_modifier; 176Lisp_Object ns_function_modifier;
167 177
@@ -223,6 +233,11 @@ static BOOL inNsSelect = 0;
223 233
224/* Convert modifiers in a NeXTSTEP event to emacs style modifiers. */ 234/* Convert modifiers in a NeXTSTEP event to emacs style modifiers. */
225#define NS_FUNCTION_KEY_MASK 0x800000 235#define NS_FUNCTION_KEY_MASK 0x800000
236#define NSLeftControlKeyMask (0x000001 | NSControlKeyMask)
237#define NSRightControlKeyMask (0x002000 | NSControlKeyMask)
238#define NSLeftCommandKeyMask (0x000008 | NSCommandKeyMask)
239#define NSRightCommandKeyMask (0x000010 | NSCommandKeyMask)
240#define NSLeftAlternateKeyMask (0x000020 | NSAlternateKeyMask)
226#define NSRightAlternateKeyMask (0x000040 | NSAlternateKeyMask) 241#define NSRightAlternateKeyMask (0x000040 | NSAlternateKeyMask)
227#define EV_MODIFIERS(e) \ 242#define EV_MODIFIERS(e) \
228 ((([e modifierFlags] & NSHelpKeyMask) ? \ 243 ((([e modifierFlags] & NSHelpKeyMask) ? \
@@ -235,10 +250,18 @@ static BOOL inNsSelect = 0;
235 parse_solitary_modifier (ns_alternate_modifier) : 0) \ 250 parse_solitary_modifier (ns_alternate_modifier) : 0) \
236 | (([e modifierFlags] & NSShiftKeyMask) ? \ 251 | (([e modifierFlags] & NSShiftKeyMask) ? \
237 shift_modifier : 0) \ 252 shift_modifier : 0) \
253 | (!EQ (ns_right_control_modifier, Qleft) && \
254 (([e modifierFlags] & NSRightControlKeyMask) \
255 == NSRightControlKeyMask) ? \
256 parse_solitary_modifier (ns_right_control_modifier) : 0) \
238 | (([e modifierFlags] & NSControlKeyMask) ? \ 257 | (([e modifierFlags] & NSControlKeyMask) ? \
239 parse_solitary_modifier (ns_control_modifier) : 0) \ 258 parse_solitary_modifier (ns_control_modifier) : 0) \
240 | (([e modifierFlags] & NS_FUNCTION_KEY_MASK) ? \ 259 | (([e modifierFlags] & NS_FUNCTION_KEY_MASK) ? \
241 parse_solitary_modifier (ns_function_modifier) : 0) \ 260 parse_solitary_modifier (ns_function_modifier) : 0) \
261 | (!EQ (ns_right_command_modifier, Qleft) && \
262 (([e modifierFlags] & NSRightCommandKeyMask) \
263 == NSRightCommandKeyMask) ? \
264 parse_solitary_modifier (ns_right_command_modifier) : 0) \
242 | (([e modifierFlags] & NSCommandKeyMask) ? \ 265 | (([e modifierFlags] & NSCommandKeyMask) ? \
243 parse_solitary_modifier (ns_command_modifier):0)) 266 parse_solitary_modifier (ns_command_modifier):0))
244 267
@@ -553,7 +576,7 @@ ns_update_window_begin (struct window *w)
553 -------------------------------------------------------------------------- */ 576 -------------------------------------------------------------------------- */
554{ 577{
555 struct frame *f = XFRAME (WINDOW_FRAME (w)); 578 struct frame *f = XFRAME (WINDOW_FRAME (w));
556 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f); 579 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
557 NSTRACE (ns_update_window_begin); 580 NSTRACE (ns_update_window_begin);
558 581
559 updated_window = w; 582 updated_window = w;
@@ -561,15 +584,15 @@ ns_update_window_begin (struct window *w)
561 584
562 BLOCK_INPUT; 585 BLOCK_INPUT;
563 586
564 if (f == dpyinfo->mouse_face_mouse_frame) 587 if (f == hlinfo->mouse_face_mouse_frame)
565 { 588 {
566 /* Don't do highlighting for mouse motion during the update. */ 589 /* Don't do highlighting for mouse motion during the update. */
567 dpyinfo->mouse_face_defer = 1; 590 hlinfo->mouse_face_defer = 1;
568 591
569 /* If the frame needs to be redrawn, 592 /* If the frame needs to be redrawn,
570 simply forget about any prior mouse highlighting. */ 593 simply forget about any prior mouse highlighting. */
571 if (FRAME_GARBAGED_P (f)) 594 if (FRAME_GARBAGED_P (f))
572 dpyinfo->mouse_face_window = Qnil; 595 hlinfo->mouse_face_window = Qnil;
573 596
574 /* (further code for mouse faces ifdef'd out in other terms elided) */ 597 /* (further code for mouse faces ifdef'd out in other terms elided) */
575 } 598 }
@@ -586,7 +609,7 @@ ns_update_window_end (struct window *w, int cursor_on_p,
586 external (RIF) call; for one window called before update_end 609 external (RIF) call; for one window called before update_end
587 -------------------------------------------------------------------------- */ 610 -------------------------------------------------------------------------- */
588{ 611{
589 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (XFRAME (w->frame)); 612 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
590 613
591 /* note: this fn is nearly identical in all terms */ 614 /* note: this fn is nearly identical in all terms */
592 if (!w->pseudo_window_p) 615 if (!w->pseudo_window_p)
@@ -608,9 +631,9 @@ ns_update_window_end (struct window *w, int cursor_on_p,
608 frame_up_to_date to redisplay the mouse highlight. */ 631 frame_up_to_date to redisplay the mouse highlight. */
609 if (mouse_face_overwritten_p) 632 if (mouse_face_overwritten_p)
610 { 633 {
611 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1; 634 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
612 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; 635 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
613 dpyinfo->mouse_face_window = Qnil; 636 hlinfo->mouse_face_window = Qnil;
614 } 637 }
615 638
616 updated_window = NULL; 639 updated_window = NULL;
@@ -627,8 +650,8 @@ ns_update_end (struct frame *f)
627{ 650{
628 NSView *view = FRAME_NS_VIEW (f); 651 NSView *view = FRAME_NS_VIEW (f);
629 652
630/* if (f == FRAME_NS_DISPLAY_INFO (f)->mouse_face_mouse_frame) */ 653/* if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */
631 FRAME_NS_DISPLAY_INFO (f)->mouse_face_defer = 0; 654 MOUSE_HL_INFO (f)->mouse_face_defer = 0;
632 655
633 BLOCK_INPUT; 656 BLOCK_INPUT;
634 657
@@ -1032,6 +1055,7 @@ x_destroy_window (struct frame *f)
1032{ 1055{
1033 NSView *view = FRAME_NS_VIEW (f); 1056 NSView *view = FRAME_NS_VIEW (f);
1034 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f); 1057 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f);
1058 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
1035 NSTRACE (x_destroy_window); 1059 NSTRACE (x_destroy_window);
1036 check_ns (); 1060 check_ns ();
1037 1061
@@ -1048,13 +1072,13 @@ x_destroy_window (struct frame *f)
1048 dpyinfo->x_focus_frame = 0; 1072 dpyinfo->x_focus_frame = 0;
1049 if (f == dpyinfo->x_highlight_frame) 1073 if (f == dpyinfo->x_highlight_frame)
1050 dpyinfo->x_highlight_frame = 0; 1074 dpyinfo->x_highlight_frame = 0;
1051 if (f == dpyinfo->mouse_face_mouse_frame) 1075 if (f == hlinfo->mouse_face_mouse_frame)
1052 { 1076 {
1053 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1; 1077 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
1054 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; 1078 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
1055 dpyinfo->mouse_face_window = Qnil; 1079 hlinfo->mouse_face_window = Qnil;
1056 dpyinfo->mouse_face_deferred_gc = 0; 1080 hlinfo->mouse_face_deferred_gc = 0;
1057 dpyinfo->mouse_face_mouse_frame = 0; 1081 hlinfo->mouse_face_mouse_frame = 0;
1058 } 1082 }
1059 1083
1060 xfree (f->output_data.ns); 1084 xfree (f->output_data.ns);
@@ -1772,18 +1796,18 @@ ns_frame_up_to_date (struct frame *f)
1772 1796
1773 if (FRAME_NS_P (f)) 1797 if (FRAME_NS_P (f))
1774 { 1798 {
1775 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (f); 1799 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
1776 if ((dpyinfo->mouse_face_deferred_gc||f ==dpyinfo->mouse_face_mouse_frame) 1800 if ((hlinfo->mouse_face_deferred_gc || f ==hlinfo->mouse_face_mouse_frame)
1777 /*&& dpyinfo->mouse_face_mouse_frame*/) 1801 /*&& hlinfo->mouse_face_mouse_frame*/)
1778 { 1802 {
1779 BLOCK_INPUT; 1803 BLOCK_INPUT;
1780 ns_update_begin(f); 1804 ns_update_begin(f);
1781 if (dpyinfo->mouse_face_mouse_frame) 1805 if (hlinfo->mouse_face_mouse_frame)
1782 note_mouse_highlight (dpyinfo->mouse_face_mouse_frame, 1806 note_mouse_highlight (hlinfo->mouse_face_mouse_frame,
1783 dpyinfo->mouse_face_mouse_x, 1807 hlinfo->mouse_face_mouse_x,
1784 dpyinfo->mouse_face_mouse_y); 1808 hlinfo->mouse_face_mouse_y);
1785 dpyinfo->mouse_face_deferred_gc = 0; 1809 hlinfo->mouse_face_deferred_gc = 0;
1786 ns_update_end(f); 1810 ns_update_end(f);
1787 UNBLOCK_INPUT; 1811 UNBLOCK_INPUT;
1788 } 1812 }
1789 } 1813 }
@@ -2595,8 +2619,7 @@ ns_dumpglyphs_box_or_relief (struct glyph_string *s)
2595 2619
2596 if (s->hl == DRAW_MOUSE_FACE) 2620 if (s->hl == DRAW_MOUSE_FACE)
2597 { 2621 {
2598 face = FACE_FROM_ID 2622 face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id);
2599 (s->f, FRAME_NS_DISPLAY_INFO (s->f)->mouse_face_face_id);
2600 if (!face) 2623 if (!face)
2601 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID); 2624 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
2602 } 2625 }
@@ -2663,8 +2686,8 @@ ns_maybe_dumpglyphs_background (struct glyph_string *s, char force_p)
2663 struct face *face; 2686 struct face *face;
2664 if (s->hl == DRAW_MOUSE_FACE) 2687 if (s->hl == DRAW_MOUSE_FACE)
2665 { 2688 {
2666 face = FACE_FROM_ID 2689 face = FACE_FROM_ID (s->f,
2667 (s->f, FRAME_NS_DISPLAY_INFO (s->f)->mouse_face_face_id); 2690 MOUSE_HL_INFO (s->f)->mouse_face_face_id);
2668 if (!face) 2691 if (!face)
2669 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID); 2692 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
2670 } 2693 }
@@ -2749,15 +2772,17 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
2749 with its background color), we must clear just the image area. */ 2772 with its background color), we must clear just the image area. */
2750 if (s->hl == DRAW_MOUSE_FACE) 2773 if (s->hl == DRAW_MOUSE_FACE)
2751 { 2774 {
2752 face = FACE_FROM_ID 2775 face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id);
2753 (s->f, FRAME_NS_DISPLAY_INFO (s->f)->mouse_face_face_id);
2754 if (!face) 2776 if (!face)
2755 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID); 2777 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
2756 } 2778 }
2757 else 2779 else
2758 face = FACE_FROM_ID (s->f, s->first_glyph->face_id); 2780 face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
2759 2781
2760 [ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f) set]; 2782 if (s->hl == DRAW_CURSOR)
2783 [FRAME_CURSOR_COLOR (s->f) set];
2784 else
2785 [ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f) set];
2761 2786
2762 if (bg_height > s->slice.height || s->img->hmargin || s->img->vmargin 2787 if (bg_height > s->slice.height || s->img->hmargin || s->img->vmargin
2763 || s->img->mask || s->img->pixmap == 0 || s->width != s->background_width) 2788 || s->img->mask || s->img->pixmap == 0 || s->width != s->background_width)
@@ -2820,6 +2845,16 @@ ns_dumpglyphs_image (struct glyph_string *s, NSRect r)
2820 s->slice.x == 0, 2845 s->slice.x == 0,
2821 s->slice.x + s->slice.width == s->img->width, s); 2846 s->slice.x + s->slice.width == s->img->width, s);
2822 } 2847 }
2848
2849 /* If there is no mask, the background won't be seen,
2850 so draw a rectangle on the image for the cursor.
2851 Do this for all images, getting trancparency right is not reliable. */
2852 if (s->hl == DRAW_CURSOR)
2853 {
2854 int thickness = abs (s->img->relief);
2855 if (thickness == 0) thickness = 1;
2856 ns_draw_box (br, thickness, FRAME_CURSOR_COLOR (s->f), 1, 1);
2857 }
2823} 2858}
2824 2859
2825 2860
@@ -2873,8 +2908,7 @@ ns_dumpglyphs_stretch (struct glyph_string *s)
2873 2908
2874 if (s->hl == DRAW_MOUSE_FACE) 2909 if (s->hl == DRAW_MOUSE_FACE)
2875 { 2910 {
2876 face = FACE_FROM_ID 2911 face = FACE_FROM_ID (s->f, MOUSE_HL_INFO (s->f)->mouse_face_face_id);
2877 (s->f, FRAME_NS_DISPLAY_INFO (s->f)->mouse_face_face_id);
2878 if (!face) 2912 if (!face)
2879 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID); 2913 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
2880 } 2914 }
@@ -2975,11 +3009,41 @@ ns_draw_glyph_string (struct glyph_string *s)
2975 if (ns_tmp_font == NULL) 3009 if (ns_tmp_font == NULL)
2976 ns_tmp_font = (struct nsfont_info *)FRAME_FONT (s->f); 3010 ns_tmp_font = (struct nsfont_info *)FRAME_FONT (s->f);
2977 3011
3012 if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR)
3013 {
3014 unsigned long tmp = NS_FACE_BACKGROUND (s->face);
3015 NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face);
3016 NS_FACE_FOREGROUND (s->face) = tmp;
3017 }
3018
2978 ns_tmp_font->font.driver->draw 3019 ns_tmp_font->font.driver->draw
2979 (s, 0, s->nchars, s->x, s->y, 3020 (s, 0, s->nchars, s->x, s->y,
2980 (ns_tmp_flags == NS_DUMPGLYPH_NORMAL && !s->background_filled_p) 3021 (ns_tmp_flags == NS_DUMPGLYPH_NORMAL && !s->background_filled_p)
2981 || ns_tmp_flags == NS_DUMPGLYPH_MOUSEFACE); 3022 || ns_tmp_flags == NS_DUMPGLYPH_MOUSEFACE);
2982 3023
3024 if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR)
3025 {
3026 unsigned long tmp = NS_FACE_BACKGROUND (s->face);
3027 NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face);
3028 NS_FACE_FOREGROUND (s->face) = tmp;
3029 }
3030
3031 ns_unfocus (s->f);
3032 break;
3033
3034 case GLYPHLESS_GLYPH:
3035 n = ns_get_glyph_string_clip_rect (s, r);
3036 ns_focus (s->f, r, n);
3037
3038 if (s->for_overlaps || (s->cmp_from > 0
3039 && ! s->first_glyph->u.cmp.automatic))
3040 s->background_filled_p = 1;
3041 else
3042 ns_maybe_dumpglyphs_background
3043 (s, s->first_glyph->type == COMPOSITE_GLYPH);
3044 /* ... */
3045 /* Not yet implemented. */
3046 /* ... */
2983 ns_unfocus (s->f); 3047 ns_unfocus (s->f);
2984 break; 3048 break;
2985 3049
@@ -3529,6 +3593,7 @@ ns_initialize_display_info (struct ns_display_info *dpyinfo)
3529{ 3593{
3530 NSScreen *screen = [NSScreen mainScreen]; 3594 NSScreen *screen = [NSScreen mainScreen];
3531 NSWindowDepth depth = [screen depth]; 3595 NSWindowDepth depth = [screen depth];
3596 Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
3532 3597
3533 dpyinfo->resx = 72.27; /* used 75.0, but this makes pt == pixel, expected */ 3598 dpyinfo->resx = 72.27; /* used 75.0, but this makes pt == pixel, expected */
3534 dpyinfo->resy = 72.27; 3599 dpyinfo->resy = 72.27;
@@ -3543,16 +3608,16 @@ ns_initialize_display_info (struct ns_display_info *dpyinfo)
3543 dpyinfo->color_table->colors = NULL; 3608 dpyinfo->color_table->colors = NULL;
3544 dpyinfo->root_window = 42; /* a placeholder.. */ 3609 dpyinfo->root_window = 42; /* a placeholder.. */
3545 3610
3546 dpyinfo->mouse_face_mouse_frame = NULL; 3611 hlinfo->mouse_face_mouse_frame = NULL;
3547 dpyinfo->mouse_face_deferred_gc = 0; 3612 hlinfo->mouse_face_deferred_gc = 0;
3548 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1; 3613 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
3549 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; 3614 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
3550 dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID; 3615 hlinfo->mouse_face_face_id = DEFAULT_FACE_ID;
3551 dpyinfo->mouse_face_window = dpyinfo->mouse_face_overlay = Qnil; 3616 hlinfo->mouse_face_window = hlinfo->mouse_face_overlay = Qnil;
3552 dpyinfo->mouse_face_hidden = 0; 3617 hlinfo->mouse_face_hidden = 0;
3553 3618
3554 dpyinfo->mouse_face_mouse_x = dpyinfo->mouse_face_mouse_y = 0; 3619 hlinfo->mouse_face_mouse_x = hlinfo->mouse_face_mouse_y = 0;
3555 dpyinfo->mouse_face_defer = 0; 3620 hlinfo->mouse_face_defer = 0;
3556 3621
3557 dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame = NULL; 3622 dpyinfo->x_highlight_frame = dpyinfo->x_focus_frame = NULL;
3558 3623
@@ -4335,7 +4400,7 @@ ns_term_shutdown (int sig)
4335 4400
4336- (void)keyDown: (NSEvent *)theEvent 4401- (void)keyDown: (NSEvent *)theEvent
4337{ 4402{
4338 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe); 4403 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (emacsframe);
4339 int code; 4404 int code;
4340 unsigned fnKeysym = 0; 4405 unsigned fnKeysym = 0;
4341 int flags; 4406 int flags;
@@ -4373,10 +4438,10 @@ ns_term_shutdown (int sig)
4373 4438
4374 [NSCursor setHiddenUntilMouseMoves: YES]; 4439 [NSCursor setHiddenUntilMouseMoves: YES];
4375 4440
4376 if (dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)) 4441 if (hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
4377 { 4442 {
4378 clear_mouse_face (dpyinfo); 4443 clear_mouse_face (hlinfo);
4379 dpyinfo->mouse_face_hidden = 1; 4444 hlinfo->mouse_face_hidden = 1;
4380 } 4445 }
4381 4446
4382 if (!processingCompose) 4447 if (!processingCompose)
@@ -4384,7 +4449,7 @@ ns_term_shutdown (int sig)
4384 code = ([[theEvent charactersIgnoringModifiers] length] == 0) ? 4449 code = ([[theEvent charactersIgnoringModifiers] length] == 0) ?
4385 0 : [[theEvent charactersIgnoringModifiers] characterAtIndex: 0]; 4450 0 : [[theEvent charactersIgnoringModifiers] characterAtIndex: 0];
4386 /* (Carbon way: [theEvent keyCode]) */ 4451 /* (Carbon way: [theEvent keyCode]) */
4387 4452
4388 /* is it a "function key"? */ 4453 /* is it a "function key"? */
4389 fnKeysym = ns_convert_key (code); 4454 fnKeysym = ns_convert_key (code);
4390 if (fnKeysym) 4455 if (fnKeysym)
@@ -4407,9 +4472,17 @@ ns_term_shutdown (int sig)
4407 if (flags & NSShiftKeyMask) 4472 if (flags & NSShiftKeyMask)
4408 emacs_event->modifiers |= shift_modifier; 4473 emacs_event->modifiers |= shift_modifier;
4409 4474
4410 if (flags & NSCommandKeyMask) 4475 if ((flags & NSRightCommandKeyMask) == NSRightCommandKeyMask)
4476 emacs_event->modifiers |= parse_solitary_modifier
4477 (EQ (ns_right_command_modifier, Qleft)
4478 ? ns_command_modifier
4479 : ns_right_command_modifier);
4480
4481 if ((flags & NSLeftCommandKeyMask) == NSLeftCommandKeyMask)
4411 { 4482 {
4412 emacs_event->modifiers |= parse_solitary_modifier (ns_command_modifier); 4483 emacs_event->modifiers |= parse_solitary_modifier
4484 (ns_command_modifier);
4485
4413 /* if super (default), take input manager's word so things like 4486 /* if super (default), take input manager's word so things like
4414 dvorak / qwerty layout work */ 4487 dvorak / qwerty layout work */
4415 if (EQ (ns_command_modifier, Qsuper) 4488 if (EQ (ns_command_modifier, Qsuper)
@@ -4442,23 +4515,43 @@ ns_term_shutdown (int sig)
4442 } 4515 }
4443 } 4516 }
4444 4517
4445 if (flags & NSControlKeyMask) 4518 if ((flags & NSRightControlKeyMask) == NSRightControlKeyMask)
4446 emacs_event->modifiers |= 4519 emacs_event->modifiers |= parse_solitary_modifier
4447 parse_solitary_modifier (ns_control_modifier); 4520 (EQ (ns_right_control_modifier, Qleft)
4521 ? ns_control_modifier
4522 : ns_right_control_modifier);
4523
4524 if ((flags & NSLeftControlKeyMask) == NSLeftControlKeyMask)
4525 emacs_event->modifiers |= parse_solitary_modifier
4526 (ns_control_modifier);
4448 4527
4449 if (flags & NS_FUNCTION_KEY_MASK && !fnKeysym) 4528 if (flags & NS_FUNCTION_KEY_MASK && !fnKeysym)
4450 emacs_event->modifiers |= 4529 emacs_event->modifiers |=
4451 parse_solitary_modifier (ns_function_modifier); 4530 parse_solitary_modifier (ns_function_modifier);
4452 4531
4453 if (!EQ (ns_right_alternate_modifier, Qleft) 4532 if ((flags & NSRightAlternateKeyMask) == NSRightAlternateKeyMask)
4454 && ((flags & NSRightAlternateKeyMask) == NSRightAlternateKeyMask))
4455 {
4456 emacs_event->modifiers |= parse_solitary_modifier
4457 (ns_right_alternate_modifier);
4458 }
4459 else if (flags & NSAlternateKeyMask) /* default = meta */
4460 { 4533 {
4461 if ((NILP (ns_alternate_modifier) || EQ (ns_alternate_modifier, Qnone)) 4534 if ((NILP (ns_right_alternate_modifier)
4535 || EQ (ns_right_alternate_modifier, Qnone))
4536 && !fnKeysym)
4537 { /* accept pre-interp alt comb */
4538 if ([[theEvent characters] length] > 0)
4539 code = [[theEvent characters] characterAtIndex: 0];
4540 /*HACK: clear lone shift modifier to stop next if from firing */
4541 if (emacs_event->modifiers == shift_modifier)
4542 emacs_event->modifiers = 0;
4543 }
4544 else
4545 emacs_event->modifiers |= parse_solitary_modifier
4546 (EQ (ns_right_alternate_modifier, Qleft)
4547 ? ns_alternate_modifier
4548 : ns_right_alternate_modifier);
4549 }
4550
4551 if ((flags & NSLeftAlternateKeyMask) == NSLeftAlternateKeyMask) /* default = meta */
4552 {
4553 if ((NILP (ns_alternate_modifier)
4554 || EQ (ns_alternate_modifier, Qnone))
4462 && !fnKeysym) 4555 && !fnKeysym)
4463 { /* accept pre-interp alt comb */ 4556 { /* accept pre-interp alt comb */
4464 if ([[theEvent characters] length] > 0) 4557 if ([[theEvent characters] length] > 0)
@@ -4813,7 +4906,7 @@ ns_term_shutdown (int sig)
4813/* Tell emacs the mouse has moved. */ 4906/* Tell emacs the mouse has moved. */
4814- (void)mouseMoved: (NSEvent *)e 4907- (void)mouseMoved: (NSEvent *)e
4815{ 4908{
4816 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe); 4909 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (emacsframe);
4817 Lisp_Object frame; 4910 Lisp_Object frame;
4818 4911
4819// NSTRACE (mouseMoved); 4912// NSTRACE (mouseMoved);
@@ -4823,10 +4916,10 @@ ns_term_shutdown (int sig)
4823 = [self convertPoint: [e locationInWindow] fromView: nil]; 4916 = [self convertPoint: [e locationInWindow] fromView: nil];
4824 4917
4825 /* update any mouse face */ 4918 /* update any mouse face */
4826 if (dpyinfo->mouse_face_hidden) 4919 if (hlinfo->mouse_face_hidden)
4827 { 4920 {
4828 dpyinfo->mouse_face_hidden = 0; 4921 hlinfo->mouse_face_hidden = 0;
4829 clear_mouse_face (dpyinfo); 4922 clear_mouse_face (hlinfo);
4830 } 4923 }
4831 4924
4832 /* tooltip handling */ 4925 /* tooltip handling */
@@ -5292,20 +5385,19 @@ ns_term_shutdown (int sig)
5292{ 5385{
5293 NSPoint p = [self convertPoint: [theEvent locationInWindow] fromView: nil]; 5386 NSPoint p = [self convertPoint: [theEvent locationInWindow] fromView: nil];
5294 NSRect r; 5387 NSRect r;
5295 struct ns_display_info *dpyinfo 5388 Mouse_HLInfo *hlinfo = emacsframe ? MOUSE_HL_INFO (emacsframe) : NULL;
5296 = emacsframe ? FRAME_NS_DISPLAY_INFO (emacsframe) : NULL;
5297 5389
5298 NSTRACE (mouseExited); 5390 NSTRACE (mouseExited);
5299 5391
5300 if (dpyinfo || !emacsframe) 5392 if (!hlinfo)
5301 return; 5393 return;
5302 5394
5303 last_mouse_movement_time = EV_TIMESTAMP (theEvent); 5395 last_mouse_movement_time = EV_TIMESTAMP (theEvent);
5304 5396
5305 if (emacsframe == dpyinfo->mouse_face_mouse_frame) 5397 if (emacsframe == hlinfo->mouse_face_mouse_frame)
5306 { 5398 {
5307 clear_mouse_face (dpyinfo); 5399 clear_mouse_face (hlinfo);
5308 dpyinfo->mouse_face_mouse_frame = 0; 5400 hlinfo->mouse_face_mouse_frame = 0;
5309 } 5401 }
5310} 5402}
5311 5403
@@ -5420,7 +5512,7 @@ ns_term_shutdown (int sig)
5420 NSTRACE (performDragOperation); 5512 NSTRACE (performDragOperation);
5421 5513
5422 if (!emacs_event) 5514 if (!emacs_event)
5423 return; 5515 return NO;
5424 5516
5425 position = [self convertPoint: [sender draggingLocation] fromView: nil]; 5517 position = [self convertPoint: [sender draggingLocation] fromView: nil];
5426 x = lrint (position.x); y = lrint (position.y); 5518 x = lrint (position.x); y = lrint (position.y);
@@ -6232,11 +6324,27 @@ at all, allowing it to be used at a lower level for accented character entry.");
6232Set to control, meta, alt, super, or hyper means it is taken to be that key."); 6324Set to control, meta, alt, super, or hyper means it is taken to be that key.");
6233 ns_command_modifier = Qsuper; 6325 ns_command_modifier = Qsuper;
6234 6326
6327 DEFVAR_LISP ("ns-right-command-modifier", &ns_right_command_modifier,
6328 "This variable describes the behavior of the right command key.\n\
6329Set to control, meta, alt, super, or hyper means it is taken to be that key.\n\
6330Set to left means be the same key as `ns-command-modifier'.\n\
6331Set to none means that the command / option key is not interpreted by Emacs\n\
6332at all, allowing it to be used at a lower level for accented character entry.");
6333 ns_right_command_modifier = Qleft;
6334
6235 DEFVAR_LISP ("ns-control-modifier", &ns_control_modifier, 6335 DEFVAR_LISP ("ns-control-modifier", &ns_control_modifier,
6236 "This variable describes the behavior of the control key.\n\ 6336 "This variable describes the behavior of the control key.\n\
6237Set to control, meta, alt, super, or hyper means it is taken to be that key."); 6337Set to control, meta, alt, super, or hyper means it is taken to be that key.");
6238 ns_control_modifier = Qcontrol; 6338 ns_control_modifier = Qcontrol;
6239 6339
6340 DEFVAR_LISP ("ns-right-control-modifier", &ns_right_control_modifier,
6341 "This variable describes the behavior of the right control key.\n\
6342Set to control, meta, alt, super, or hyper means it is taken to be that key.\n\
6343Set to left means be the same key as `ns-control-modifier'.\n\
6344Set to none means that the control / option key is not interpreted by Emacs\n\
6345at all, allowing it to be used at a lower level for accented character entry.");
6346 ns_right_control_modifier = Qleft;
6347
6240 DEFVAR_LISP ("ns-function-modifier", &ns_function_modifier, 6348 DEFVAR_LISP ("ns-function-modifier", &ns_function_modifier,
6241 "This variable describes the behavior of the function key (on laptops).\n\ 6349 "This variable describes the behavior of the function key (on laptops).\n\
6242Set to control, meta, alt, super, or hyper means it is taken to be that key.\n\ 6350Set to control, meta, alt, super, or hyper means it is taken to be that key.\n\