aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Third2018-09-29 17:08:43 +0100
committerAlan Third2018-09-29 17:08:43 +0100
commit6217746dd64b43a2a2b3b66ab50cfbbfc984f36c (patch)
treea3f8707c17a5d8e9e1ba1a433cb9cde6ffb9f400 /src
parentfcea30604254e1e77eaa88d9b4d15dd048d41233 (diff)
parent9ad0f1d15c06eb07dfbd9bd3e3b8a0d747942152 (diff)
downloademacs-6217746dd64b43a2a2b3b66ab50cfbbfc984f36c.tar.gz
emacs-6217746dd64b43a2a2b3b66ab50cfbbfc984f36c.zip
Merge from origin/emacs-26
9ad0f1d15c Fix deprecation warning 7946445962 Make all NS drawing be done from drawRect 41fa88b99b ; Fix some doc typos
Diffstat (limited to 'src')
-rw-r--r--src/nsterm.m781
1 files changed, 390 insertions, 391 deletions
diff --git a/src/nsterm.m b/src/nsterm.m
index 961271f2d05..68ad64660ca 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -278,12 +278,7 @@ struct ns_display_info *x_display_list; /* Chain of existing displays */
278long context_menu_value = 0; 278long context_menu_value = 0;
279 279
280/* display update */ 280/* display update */
281static struct frame *ns_updating_frame;
282static NSView *focus_view = NULL;
283static int ns_window_num = 0; 281static int ns_window_num = 0;
284#ifdef NS_IMPL_GNUSTEP
285static NSRect uRect; // TODO: This is dead, remove it?
286#endif
287static BOOL gsaved = NO; 282static BOOL gsaved = NO;
288static BOOL ns_fake_keydown = NO; 283static BOOL ns_fake_keydown = NO;
289#ifdef NS_IMPL_COCOA 284#ifdef NS_IMPL_COCOA
@@ -1093,12 +1088,13 @@ ns_update_begin (struct frame *f)
1093 external (RIF) call; whole frame, called before update_window_begin 1088 external (RIF) call; whole frame, called before update_window_begin
1094 -------------------------------------------------------------------------- */ 1089 -------------------------------------------------------------------------- */
1095{ 1090{
1091#ifdef NS_IMPL_COCOA
1096 EmacsView *view = FRAME_NS_VIEW (f); 1092 EmacsView *view = FRAME_NS_VIEW (f);
1093
1097 NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_begin"); 1094 NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_begin");
1098 1095
1099 ns_update_auto_hide_menu_bar (); 1096 ns_update_auto_hide_menu_bar ();
1100 1097
1101#ifdef NS_IMPL_COCOA
1102 if ([view isFullscreen] && [view fsIsNative]) 1098 if ([view isFullscreen] && [view fsIsNative])
1103 { 1099 {
1104 // Fix reappearing tool bar in fullscreen for Mac OS X 10.7 1100 // Fix reappearing tool bar in fullscreen for Mac OS X 10.7
@@ -1107,36 +1103,29 @@ ns_update_begin (struct frame *f)
1107 if (! tbar_visible != ! [toolbar isVisible]) 1103 if (! tbar_visible != ! [toolbar isVisible])
1108 [toolbar setVisible: tbar_visible]; 1104 [toolbar setVisible: tbar_visible];
1109 } 1105 }
1110#endif
1111
1112 ns_updating_frame = f;
1113 [view lockFocus];
1114 1106
1115 /* drawRect may have been called for say the minibuffer, and then clip path 1107 /* drawRect may have been called for say the minibuffer, and then clip path
1116 is for the minibuffer. But the display engine may draw more because 1108 is for the minibuffer. But the display engine may draw more because
1117 we have set the frame as garbaged. So reset clip path to the whole 1109 we have set the frame as garbaged. So reset clip path to the whole
1118 view. */ 1110 view. */
1119#ifdef NS_IMPL_COCOA 1111 /* FIXME: I don't think we need to do this. */
1120 { 1112 if ([NSView focusView] == FRAME_NS_VIEW (f))
1121 NSBezierPath *bp; 1113 {
1122 NSRect r = [view frame]; 1114 NSBezierPath *bp;
1123 NSRect cr = [[view window] frame]; 1115 NSRect r = [view frame];
1124 /* If a large frame size is set, r may be larger than the window frame 1116 NSRect cr = [[view window] frame];
1125 before constrained. In that case don't change the clip path, as we 1117 /* If a large frame size is set, r may be larger than the window frame
1126 will clear in to the tool bar and title bar. */ 1118 before constrained. In that case don't change the clip path, as we
1127 if (r.size.height 1119 will clear in to the tool bar and title bar. */
1128 + FRAME_NS_TITLEBAR_HEIGHT (f) 1120 if (r.size.height
1129 + FRAME_TOOLBAR_HEIGHT (f) <= cr.size.height) 1121 + FRAME_NS_TITLEBAR_HEIGHT (f)
1130 { 1122 + FRAME_TOOLBAR_HEIGHT (f) <= cr.size.height)
1131 bp = [[NSBezierPath bezierPathWithRect: r] retain]; 1123 {
1132 [bp setClip]; 1124 bp = [[NSBezierPath bezierPathWithRect: r] retain];
1133 [bp release]; 1125 [bp setClip];
1134 } 1126 [bp release];
1135 } 1127 }
1136#endif 1128 }
1137
1138#ifdef NS_IMPL_GNUSTEP
1139 uRect = NSMakeRect (0, 0, 0, 0);
1140#endif 1129#endif
1141} 1130}
1142 1131
@@ -1218,99 +1207,66 @@ ns_update_end (struct frame *f)
1218 external (RIF) call; for whole frame, called after update_window_end 1207 external (RIF) call; for whole frame, called after update_window_end
1219 -------------------------------------------------------------------------- */ 1208 -------------------------------------------------------------------------- */
1220{ 1209{
1221 EmacsView *view = FRAME_NS_VIEW (f);
1222
1223 NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_end"); 1210 NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_update_end");
1224 1211
1225/* if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */ 1212/* if (f == MOUSE_HL_INFO (f)->mouse_face_mouse_frame) */
1226 MOUSE_HL_INFO (f)->mouse_face_defer = 0; 1213 MOUSE_HL_INFO (f)->mouse_face_defer = 0;
1227
1228 block_input ();
1229
1230 [view unlockFocus];
1231 [[view window] flushWindow];
1232
1233 unblock_input ();
1234 ns_updating_frame = NULL;
1235} 1214}
1236 1215
1237static void 1216
1238ns_focus (struct frame *f, NSRect *r, int n) 1217static BOOL
1218ns_clip_to_rect (struct frame *f, NSRect *r, int n)
1239/* -------------------------------------------------------------------------- 1219/* --------------------------------------------------------------------------
1240 Internal: Focus on given frame. During small local updates this is used to 1220 Clip the drawing area to rectangle r in frame f. If drawing is not
1241 draw, however during large updates, ns_update_begin and ns_update_end are 1221 currently possible mark r as dirty and return NO, otherwise return
1242 called to wrap the whole thing, in which case these calls are stubbed out. 1222 YES.
1243 Except, on GNUstep, we accumulate the rectangle being drawn into, because
1244 the back end won't do this automatically, and will just end up flushing
1245 the entire window.
1246 -------------------------------------------------------------------------- */ 1223 -------------------------------------------------------------------------- */
1247{ 1224{
1248 NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_focus"); 1225 NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_clip_to_rect");
1249 if (r != NULL) 1226 if (r)
1250 { 1227 {
1251 NSTRACE_RECT ("r", *r); 1228 NSTRACE_RECT ("r", *r);
1252 }
1253 1229
1254 if (f != ns_updating_frame) 1230 if ([NSView focusView] == FRAME_NS_VIEW (f))
1255 {
1256 NSView *view = FRAME_NS_VIEW (f);
1257 if (view != focus_view)
1258 { 1231 {
1259 if (focus_view != NULL) 1232 [[NSGraphicsContext currentContext] saveGraphicsState];
1260 { 1233 if (n == 2)
1261 [focus_view unlockFocus]; 1234 NSRectClipList (r, 2);
1262 [[focus_view window] flushWindow]; 1235 else
1263/* debug_lock--; */ 1236 NSRectClip (*r);
1264 } 1237 gsaved = YES;
1265 1238
1266 if (view) 1239 return YES;
1267 [view lockFocus];
1268 focus_view = view;
1269/* if (view) debug_lock++; */
1270 } 1240 }
1271 }
1272
1273 /* clipping */
1274 if (r)
1275 {
1276 [[NSGraphicsContext currentContext] saveGraphicsState];
1277 if (n == 2)
1278 NSRectClipList (r, 2);
1279 else 1241 else
1280 NSRectClip (*r); 1242 {
1281 gsaved = YES; 1243 NSView *view = FRAME_NS_VIEW (f);
1244 int i;
1245 for (i = 0 ; i < n ; i++)
1246 [view setNeedsDisplayInRect:r[i]];
1247 }
1282 } 1248 }
1249
1250 return NO;
1283} 1251}
1284 1252
1285 1253
1286static void 1254static void
1287ns_unfocus (struct frame *f) 1255ns_reset_clipping (struct frame *f)
1288/* -------------------------------------------------------------------------- 1256/* Internal: Restore the previous graphics state, unsetting any
1289 Internal: Remove focus on given frame 1257 clipping areas. */
1290 -------------------------------------------------------------------------- */
1291{ 1258{
1292 NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_unfocus"); 1259 NSTRACE_WHEN (NSTRACE_GROUP_FOCUS, "ns_reset_clipping");
1293 1260
1294 if (gsaved) 1261 if (gsaved)
1295 { 1262 {
1296 [[NSGraphicsContext currentContext] restoreGraphicsState]; 1263 [[NSGraphicsContext currentContext] restoreGraphicsState];
1297 gsaved = NO; 1264 gsaved = NO;
1298 } 1265 }
1299
1300 if (f != ns_updating_frame)
1301 {
1302 if (focus_view != NULL)
1303 {
1304 [focus_view unlockFocus];
1305 [[focus_view window] flushWindow];
1306 focus_view = NULL;
1307/* debug_lock--; */
1308 }
1309 }
1310} 1266}
1311 1267
1312 1268
1313static void 1269static BOOL
1314ns_clip_to_row (struct window *w, struct glyph_row *row, 1270ns_clip_to_row (struct window *w, struct glyph_row *row,
1315 enum glyph_row_area area, BOOL gc) 1271 enum glyph_row_area area, BOOL gc)
1316/* -------------------------------------------------------------------------- 1272/* --------------------------------------------------------------------------
@@ -1329,7 +1285,19 @@ ns_clip_to_row (struct window *w, struct glyph_row *row,
1329 clip_rect.size.width = window_width; 1285 clip_rect.size.width = window_width;
1330 clip_rect.size.height = row->visible_height; 1286 clip_rect.size.height = row->visible_height;
1331 1287
1332 ns_focus (f, &clip_rect, 1); 1288 return ns_clip_to_rect (f, &clip_rect, 1);
1289}
1290
1291
1292static void
1293ns_flush_display (struct frame *f)
1294/* Force the frame to redisplay. If areas have previously been marked
1295 dirty by setNeedsDisplayInRect (in ns_clip_to_rect), then this will call
1296 draw_rect: which will "expose" those areas. */
1297{
1298 block_input ();
1299 [FRAME_NS_VIEW (f) displayIfNeeded];
1300 unblock_input ();
1333} 1301}
1334 1302
1335 1303
@@ -2826,14 +2794,16 @@ ns_clear_frame (struct frame *f)
2826 r = [view bounds]; 2794 r = [view bounds];
2827 2795
2828 block_input (); 2796 block_input ();
2829 ns_focus (f, &r, 1); 2797 if (ns_clip_to_rect (f, &r, 1))
2830 [ns_lookup_indexed_color (NS_FACE_BACKGROUND 2798 {
2831 (FACE_FROM_ID (f, DEFAULT_FACE_ID)), f) set]; 2799 [ns_lookup_indexed_color (NS_FACE_BACKGROUND
2832 NSRectFill (r); 2800 (FACE_FROM_ID (f, DEFAULT_FACE_ID)), f) set];
2833 ns_unfocus (f); 2801 NSRectFill (r);
2834 2802 ns_reset_clipping (f);
2835 /* as of 2006/11 or so this is now needed */ 2803
2836 ns_redraw_scroll_bars (f); 2804 /* as of 2006/11 or so this is now needed */
2805 ns_redraw_scroll_bars (f);
2806 }
2837 unblock_input (); 2807 unblock_input ();
2838} 2808}
2839 2809
@@ -2854,13 +2824,14 @@ ns_clear_frame_area (struct frame *f, int x, int y, int width, int height)
2854 NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_clear_frame_area"); 2824 NSTRACE_WHEN (NSTRACE_GROUP_UPDATES, "ns_clear_frame_area");
2855 2825
2856 r = NSIntersectionRect (r, [view frame]); 2826 r = NSIntersectionRect (r, [view frame]);
2857 ns_focus (f, &r, 1); 2827 if (ns_clip_to_rect (f, &r, 1))
2858 [ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f) set]; 2828 {
2829 [ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), f) set];
2859 2830
2860 NSRectFill (r); 2831 NSRectFill (r);
2861 2832
2862 ns_unfocus (f); 2833 ns_reset_clipping (f);
2863 return; 2834 }
2864} 2835}
2865 2836
2866static void 2837static void
@@ -2872,11 +2843,11 @@ ns_copy_bits (struct frame *f, NSRect src, NSRect dest)
2872 { 2843 {
2873 hide_bell(); // Ensure the bell image isn't scrolled. 2844 hide_bell(); // Ensure the bell image isn't scrolled.
2874 2845
2875 ns_focus (f, &dest, 1); 2846 /* FIXME: scrollRect:by: is deprecated in macOS 10.14. There is
2847 no obvious replacement so we may have to come up with our own. */
2876 [FRAME_NS_VIEW (f) scrollRect: src 2848 [FRAME_NS_VIEW (f) scrollRect: src
2877 by: NSMakeSize (dest.origin.x - src.origin.x, 2849 by: NSMakeSize (dest.origin.x - src.origin.x,
2878 dest.origin.y - src.origin.y)]; 2850 dest.origin.y - src.origin.y)];
2879 ns_unfocus (f);
2880 } 2851 }
2881} 2852}
2882 2853
@@ -3087,85 +3058,86 @@ ns_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
3087 } 3058 }
3088 3059
3089 /* Must clip because of partially visible lines. */ 3060 /* Must clip because of partially visible lines. */
3090 ns_clip_to_row (w, row, ANY_AREA, YES); 3061 if (ns_clip_to_row (w, row, ANY_AREA, YES))
3091
3092 if (!p->overlay_p)
3093 { 3062 {
3094 int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny; 3063 if (!p->overlay_p)
3095
3096 if (bx >= 0 && nx > 0)
3097 { 3064 {
3098 NSRect r = NSMakeRect (bx, by, nx, ny); 3065 int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny;
3099 NSRectClip (r);
3100 [ns_lookup_indexed_color (face->background, f) set];
3101 NSRectFill (r);
3102 }
3103 }
3104 3066
3105 if (p->which) 3067 if (bx >= 0 && nx > 0)
3106 { 3068 {
3107 NSRect r = NSMakeRect (p->x, p->y, p->wd, p->h); 3069 NSRect r = NSMakeRect (bx, by, nx, ny);
3108 EmacsImage *img = bimgs[p->which - 1]; 3070 NSRectClip (r);
3109 3071 [ns_lookup_indexed_color (face->background, f) set];
3110 if (!img) 3072 NSRectFill (r);
3111 { 3073 }
3112 // Note: For "periodic" images, allocate one EmacsImage for
3113 // the base image, and use it for all dh:s.
3114 unsigned short *bits = p->bits;
3115 int full_height = p->h + p->dh;
3116 int i;
3117 unsigned char *cbits = xmalloc (full_height);
3118
3119 for (i = 0; i < full_height; i++)
3120 cbits[i] = bits[i];
3121 img = [[EmacsImage alloc] initFromXBM: cbits width: 8
3122 height: full_height
3123 fg: 0 bg: 0];
3124 bimgs[p->which - 1] = img;
3125 xfree (cbits);
3126 } 3074 }
3127 3075
3128 NSTRACE_RECT ("r", r); 3076 if (p->which)
3077 {
3078 NSRect r = NSMakeRect (p->x, p->y, p->wd, p->h);
3079 EmacsImage *img = bimgs[p->which - 1];
3129 3080
3130 NSRectClip (r); 3081 if (!img)
3131 /* Since we composite the bitmap instead of just blitting it, we need 3082 {
3132 to erase the whole background. */ 3083 // Note: For "periodic" images, allocate one EmacsImage for
3133 [ns_lookup_indexed_color(face->background, f) set]; 3084 // the base image, and use it for all dh:s.
3134 NSRectFill (r); 3085 unsigned short *bits = p->bits;
3086 int full_height = p->h + p->dh;
3087 int i;
3088 unsigned char *cbits = xmalloc (full_height);
3089
3090 for (i = 0; i < full_height; i++)
3091 cbits[i] = bits[i];
3092 img = [[EmacsImage alloc] initFromXBM: cbits width: 8
3093 height: full_height
3094 fg: 0 bg: 0];
3095 bimgs[p->which - 1] = img;
3096 xfree (cbits);
3097 }
3135 3098
3136 { 3099 NSTRACE_RECT ("r", r);
3137 NSColor *bm_color;
3138 if (!p->cursor_p)
3139 bm_color = ns_lookup_indexed_color(face->foreground, f);
3140 else if (p->overlay_p)
3141 bm_color = ns_lookup_indexed_color(face->background, f);
3142 else
3143 bm_color = f->output_data.ns->cursor_color;
3144 [img setXBMColor: bm_color];
3145 }
3146 3100
3147#ifdef NS_IMPL_COCOA 3101 NSRectClip (r);
3148 // Note: For periodic images, the full image height is "h + hd". 3102 /* Since we composite the bitmap instead of just blitting it, we need
3149 // By using the height h, a suitable part of the image is used. 3103 to erase the whole background. */
3150 NSRect fromRect = NSMakeRect(0, 0, p->wd, p->h); 3104 [ns_lookup_indexed_color(face->background, f) set];
3105 NSRectFill (r);
3151 3106
3152 NSTRACE_RECT ("fromRect", fromRect); 3107 {
3108 NSColor *bm_color;
3109 if (!p->cursor_p)
3110 bm_color = ns_lookup_indexed_color(face->foreground, f);
3111 else if (p->overlay_p)
3112 bm_color = ns_lookup_indexed_color(face->background, f);
3113 else
3114 bm_color = f->output_data.ns->cursor_color;
3115 [img setXBMColor: bm_color];
3116 }
3153 3117
3154 [img drawInRect: r 3118#ifdef NS_IMPL_COCOA
3155 fromRect: fromRect 3119 // Note: For periodic images, the full image height is "h + hd".
3156 operation: NSCompositingOperationSourceOver 3120 // By using the height h, a suitable part of the image is used.
3157 fraction: 1.0 3121 NSRect fromRect = NSMakeRect(0, 0, p->wd, p->h);
3158 respectFlipped: YES 3122
3159 hints: nil]; 3123 NSTRACE_RECT ("fromRect", fromRect);
3124
3125 [img drawInRect: r
3126 fromRect: fromRect
3127 operation: NSCompositingOperationSourceOver
3128 fraction: 1.0
3129 respectFlipped: YES
3130 hints: nil];
3160#else 3131#else
3161 { 3132 {
3162 NSPoint pt = r.origin; 3133 NSPoint pt = r.origin;
3163 pt.y += p->h; 3134 pt.y += p->h;
3164 [img compositeToPoint: pt operation: NSCompositingOperationSourceOver]; 3135 [img compositeToPoint: pt operation: NSCompositingOperationSourceOver];
3165 } 3136 }
3166#endif 3137#endif
3138 }
3139 ns_reset_clipping (f);
3167 } 3140 }
3168 ns_unfocus (f);
3169} 3141}
3170 3142
3171 3143
@@ -3248,66 +3220,65 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
3248 r.size.width = w->phys_cursor_width; 3220 r.size.width = w->phys_cursor_width;
3249 3221
3250 /* Prevent the cursor from being drawn outside the text area. */ 3222 /* Prevent the cursor from being drawn outside the text area. */
3251 ns_clip_to_row (w, glyph_row, TEXT_AREA, NO); /* do ns_focus(f, &r, 1); if remove */ 3223 if (ns_clip_to_row (w, glyph_row, TEXT_AREA, NO))
3252
3253
3254 face = FACE_FROM_ID_OR_NULL (f, phys_cursor_glyph->face_id);
3255 if (face && NS_FACE_BACKGROUND (face)
3256 == ns_index_color (FRAME_CURSOR_COLOR (f), f))
3257 { 3224 {
3258 [ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), f) set]; 3225 face = FACE_FROM_ID_OR_NULL (f, phys_cursor_glyph->face_id);
3259 hollow_color = FRAME_CURSOR_COLOR (f); 3226 if (face && NS_FACE_BACKGROUND (face)
3260 } 3227 == ns_index_color (FRAME_CURSOR_COLOR (f), f))
3261 else 3228 {
3262 [FRAME_CURSOR_COLOR (f) set]; 3229 [ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), f) set];
3230 hollow_color = FRAME_CURSOR_COLOR (f);
3231 }
3232 else
3233 [FRAME_CURSOR_COLOR (f) set];
3263 3234
3264#ifdef NS_IMPL_COCOA 3235#ifdef NS_IMPL_COCOA
3265 /* TODO: This makes drawing of cursor plus that of phys_cursor_glyph 3236 /* TODO: This makes drawing of cursor plus that of phys_cursor_glyph
3266 atomic. Cleaner ways of doing this should be investigated. 3237 atomic. Cleaner ways of doing this should be investigated.
3267 One way would be to set a global variable DRAWING_CURSOR 3238 One way would be to set a global variable DRAWING_CURSOR
3268 when making the call to draw_phys..(), don't focus in that 3239 when making the call to draw_phys..(), don't focus in that
3269 case, then move the ns_unfocus() here after that call. */ 3240 case, then move the ns_reset_clipping() here after that call. */
3270 NSDisableScreenUpdates (); 3241 NSDisableScreenUpdates ();
3271#endif 3242#endif
3272 3243
3273 switch (cursor_type) 3244 switch (cursor_type)
3274 { 3245 {
3275 case DEFAULT_CURSOR: 3246 case DEFAULT_CURSOR:
3276 case NO_CURSOR: 3247 case NO_CURSOR:
3277 break; 3248 break;
3278 case FILLED_BOX_CURSOR: 3249 case FILLED_BOX_CURSOR:
3279 NSRectFill (r); 3250 NSRectFill (r);
3280 break; 3251 break;
3281 case HOLLOW_BOX_CURSOR: 3252 case HOLLOW_BOX_CURSOR:
3282 NSRectFill (r); 3253 NSRectFill (r);
3283 [hollow_color set]; 3254 [hollow_color set];
3284 NSRectFill (NSInsetRect (r, 1, 1)); 3255 NSRectFill (NSInsetRect (r, 1, 1));
3285 [FRAME_CURSOR_COLOR (f) set]; 3256 [FRAME_CURSOR_COLOR (f) set];
3286 break; 3257 break;
3287 case HBAR_CURSOR: 3258 case HBAR_CURSOR:
3288 NSRectFill (r); 3259 NSRectFill (r);
3289 break; 3260 break;
3290 case BAR_CURSOR: 3261 case BAR_CURSOR:
3291 s = r; 3262 s = r;
3292 /* If the character under cursor is R2L, draw the bar cursor 3263 /* If the character under cursor is R2L, draw the bar cursor
3293 on the right of its glyph, rather than on the left. */ 3264 on the right of its glyph, rather than on the left. */
3294 cursor_glyph = get_phys_cursor_glyph (w); 3265 cursor_glyph = get_phys_cursor_glyph (w);
3295 if ((cursor_glyph->resolved_level & 1) != 0) 3266 if ((cursor_glyph->resolved_level & 1) != 0)
3296 s.origin.x += cursor_glyph->pixel_width - s.size.width; 3267 s.origin.x += cursor_glyph->pixel_width - s.size.width;
3297 3268
3298 NSRectFill (s); 3269 NSRectFill (s);
3299 break; 3270 break;
3300 } 3271 }
3301 ns_unfocus (f); 3272 ns_reset_clipping (f);
3302 3273
3303 /* draw the character under the cursor */ 3274 /* draw the character under the cursor */
3304 if (cursor_type != NO_CURSOR) 3275 if (cursor_type != NO_CURSOR)
3305 draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); 3276 draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
3306 3277
3307#ifdef NS_IMPL_COCOA 3278#ifdef NS_IMPL_COCOA
3308 NSEnableScreenUpdates (); 3279 NSEnableScreenUpdates ();
3309#endif 3280#endif
3310 3281 }
3311} 3282}
3312 3283
3313 3284
@@ -3325,12 +3296,14 @@ ns_draw_vertical_window_border (struct window *w, int x, int y0, int y1)
3325 3296
3326 face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID); 3297 face = FACE_FROM_ID_OR_NULL (f, VERTICAL_BORDER_FACE_ID);
3327 3298
3328 ns_focus (f, &r, 1); 3299 if (ns_clip_to_rect (f, &r, 1))
3329 if (face) 3300 {
3330 [ns_lookup_indexed_color(face->foreground, f) set]; 3301 if (face)
3302 [ns_lookup_indexed_color(face->foreground, f) set];
3331 3303
3332 NSRectFill(r); 3304 NSRectFill(r);
3333 ns_unfocus (f); 3305 ns_reset_clipping (f);
3306 }
3334} 3307}
3335 3308
3336 3309
@@ -3357,39 +3330,40 @@ ns_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
3357 3330
3358 NSTRACE ("ns_draw_window_divider"); 3331 NSTRACE ("ns_draw_window_divider");
3359 3332
3360 ns_focus (f, &divider, 1); 3333 if (ns_clip_to_rect (f, &divider, 1))
3361
3362 if ((y1 - y0 > x1 - x0) && (x1 - x0 >= 3))
3363 /* A vertical divider, at least three pixels wide: Draw first and
3364 last pixels differently. */
3365 {
3366 [ns_lookup_indexed_color(color_first, f) set];
3367 NSRectFill(NSMakeRect (x0, y0, 1, y1 - y0));
3368 [ns_lookup_indexed_color(color, f) set];
3369 NSRectFill(NSMakeRect (x0 + 1, y0, x1 - x0 - 2, y1 - y0));
3370 [ns_lookup_indexed_color(color_last, f) set];
3371 NSRectFill(NSMakeRect (x1 - 1, y0, 1, y1 - y0));
3372 }
3373 else if ((x1 - x0 > y1 - y0) && (y1 - y0 >= 3))
3374 /* A horizontal divider, at least three pixels high: Draw first and
3375 last pixels differently. */
3376 { 3334 {
3377 [ns_lookup_indexed_color(color_first, f) set]; 3335 if ((y1 - y0 > x1 - x0) && (x1 - x0 >= 3))
3378 NSRectFill(NSMakeRect (x0, y0, x1 - x0, 1)); 3336 /* A vertical divider, at least three pixels wide: Draw first and
3379 [ns_lookup_indexed_color(color, f) set]; 3337 last pixels differently. */
3380 NSRectFill(NSMakeRect (x0, y0 + 1, x1 - x0, y1 - y0 - 2)); 3338 {
3381 [ns_lookup_indexed_color(color_last, f) set]; 3339 [ns_lookup_indexed_color(color_first, f) set];
3382 NSRectFill(NSMakeRect (x0, y1 - 1, x1 - x0, 1)); 3340 NSRectFill(NSMakeRect (x0, y0, 1, y1 - y0));
3383 } 3341 [ns_lookup_indexed_color(color, f) set];
3384 else 3342 NSRectFill(NSMakeRect (x0 + 1, y0, x1 - x0 - 2, y1 - y0));
3385 { 3343 [ns_lookup_indexed_color(color_last, f) set];
3386 /* In any other case do not draw the first and last pixels 3344 NSRectFill(NSMakeRect (x1 - 1, y0, 1, y1 - y0));
3387 differently. */ 3345 }
3388 [ns_lookup_indexed_color(color, f) set]; 3346 else if ((x1 - x0 > y1 - y0) && (y1 - y0 >= 3))
3389 NSRectFill(divider); 3347 /* A horizontal divider, at least three pixels high: Draw first and
3390 } 3348 last pixels differently. */
3349 {
3350 [ns_lookup_indexed_color(color_first, f) set];
3351 NSRectFill(NSMakeRect (x0, y0, x1 - x0, 1));
3352 [ns_lookup_indexed_color(color, f) set];
3353 NSRectFill(NSMakeRect (x0, y0 + 1, x1 - x0, y1 - y0 - 2));
3354 [ns_lookup_indexed_color(color_last, f) set];
3355 NSRectFill(NSMakeRect (x0, y1 - 1, x1 - x0, 1));
3356 }
3357 else
3358 {
3359 /* In any other case do not draw the first and last pixels
3360 differently. */
3361 [ns_lookup_indexed_color(color, f) set];
3362 NSRectFill(divider);
3363 }
3391 3364
3392 ns_unfocus (f); 3365 ns_reset_clipping (f);
3366 }
3393} 3367}
3394 3368
3395static void 3369static void
@@ -3988,83 +3962,84 @@ ns_dumpglyphs_stretch (struct glyph_string *s)
3988 n = ns_get_glyph_string_clip_rect (s, r); 3962 n = ns_get_glyph_string_clip_rect (s, r);
3989 *r = NSMakeRect (s->x, s->y, s->background_width, s->height); 3963 *r = NSMakeRect (s->x, s->y, s->background_width, s->height);
3990 3964
3991 ns_focus (s->f, r, n); 3965 if (ns_clip_to_rect (s->f, r, n))
3992
3993 if (s->hl == DRAW_MOUSE_FACE)
3994 {
3995 face = FACE_FROM_ID_OR_NULL (s->f,
3996 MOUSE_HL_INFO (s->f)->mouse_face_face_id);
3997 if (!face)
3998 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
3999 }
4000 else
4001 face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
4002
4003 bgCol = ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f);
4004 fgCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f);
4005
4006 for (i = 0; i < n; ++i)
4007 { 3966 {
4008 if (!s->row->full_width_p) 3967 if (s->hl == DRAW_MOUSE_FACE)
4009 { 3968 {
4010 int overrun, leftoverrun; 3969 face = FACE_FROM_ID_OR_NULL (s->f,
4011 3970 MOUSE_HL_INFO (s->f)->mouse_face_face_id);
4012 /* truncate to avoid overwriting fringe and/or scrollbar */ 3971 if (!face)
4013 overrun = max (0, (s->x + s->background_width) 3972 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
4014 - (WINDOW_BOX_RIGHT_EDGE_X (s->w)
4015 - WINDOW_RIGHT_FRINGE_WIDTH (s->w)));
4016 r[i].size.width -= overrun;
4017
4018 /* truncate to avoid overwriting to left of the window box */
4019 leftoverrun = (WINDOW_BOX_LEFT_EDGE_X (s->w)
4020 + WINDOW_LEFT_FRINGE_WIDTH (s->w)) - s->x;
4021
4022 if (leftoverrun > 0)
4023 {
4024 r[i].origin.x += leftoverrun;
4025 r[i].size.width -= leftoverrun;
4026 }
4027
4028 /* XXX: Try to work between problem where a stretch glyph on
4029 a partially-visible bottom row will clear part of the
4030 modeline, and another where list-buffers headers and similar
4031 rows erroneously have visible_height set to 0. Not sure
4032 where this is coming from as other terms seem not to show. */
4033 r[i].size.height = min (s->height, s->row->visible_height);
4034 } 3973 }
3974 else
3975 face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
4035 3976
4036 [bgCol set]; 3977 bgCol = ns_lookup_indexed_color (NS_FACE_BACKGROUND (face), s->f);
3978 fgCol = ns_lookup_indexed_color (NS_FACE_FOREGROUND (face), s->f);
4037 3979
4038 /* NOTE: under NS this is NOT used to draw cursors, but we must avoid 3980 for (i = 0; i < n; ++i)
4039 overwriting cursor (usually when cursor on a tab). */
4040 if (s->hl == DRAW_CURSOR)
4041 { 3981 {
4042 CGFloat x, width; 3982 if (!s->row->full_width_p)
3983 {
3984 int overrun, leftoverrun;
3985
3986 /* truncate to avoid overwriting fringe and/or scrollbar */
3987 overrun = max (0, (s->x + s->background_width)
3988 - (WINDOW_BOX_RIGHT_EDGE_X (s->w)
3989 - WINDOW_RIGHT_FRINGE_WIDTH (s->w)));
3990 r[i].size.width -= overrun;
3991
3992 /* truncate to avoid overwriting to left of the window box */
3993 leftoverrun = (WINDOW_BOX_LEFT_EDGE_X (s->w)
3994 + WINDOW_LEFT_FRINGE_WIDTH (s->w)) - s->x;
3995
3996 if (leftoverrun > 0)
3997 {
3998 r[i].origin.x += leftoverrun;
3999 r[i].size.width -= leftoverrun;
4000 }
4001
4002 /* XXX: Try to work between problem where a stretch glyph on
4003 a partially-visible bottom row will clear part of the
4004 modeline, and another where list-buffers headers and similar
4005 rows erroneously have visible_height set to 0. Not sure
4006 where this is coming from as other terms seem not to show. */
4007 r[i].size.height = min (s->height, s->row->visible_height);
4008 }
4009
4010 [bgCol set];
4043 4011
4044 x = r[i].origin.x; 4012 /* NOTE: under NS this is NOT used to draw cursors, but we must avoid
4045 width = s->w->phys_cursor_width; 4013 overwriting cursor (usually when cursor on a tab). */
4046 r[i].size.width -= width; 4014 if (s->hl == DRAW_CURSOR)
4047 r[i].origin.x += width; 4015 {
4016 CGFloat x, width;
4017
4018 x = r[i].origin.x;
4019 width = s->w->phys_cursor_width;
4020 r[i].size.width -= width;
4021 r[i].origin.x += width;
4048 4022
4049 NSRectFill (r[i]); 4023 NSRectFill (r[i]);
4050 4024
4051 /* Draw overlining, etc. on the cursor. */ 4025 /* Draw overlining, etc. on the cursor. */
4052 if (s->w->phys_cursor_type == FILLED_BOX_CURSOR) 4026 if (s->w->phys_cursor_type == FILLED_BOX_CURSOR)
4053 ns_draw_text_decoration (s, face, bgCol, width, x); 4027 ns_draw_text_decoration (s, face, bgCol, width, x);
4028 else
4029 ns_draw_text_decoration (s, face, fgCol, width, x);
4030 }
4054 else 4031 else
4055 ns_draw_text_decoration (s, face, fgCol, width, x); 4032 {
4056 } 4033 NSRectFill (r[i]);
4057 else 4034 }
4058 {
4059 NSRectFill (r[i]);
4060 }
4061 4035
4062 /* Draw overlining, etc. on the stretch glyph (or the part 4036 /* Draw overlining, etc. on the stretch glyph (or the part
4063 of the stretch glyph after the cursor). */ 4037 of the stretch glyph after the cursor). */
4064 ns_draw_text_decoration (s, face, fgCol, r[i].size.width, 4038 ns_draw_text_decoration (s, face, fgCol, r[i].size.width,
4065 r[i].origin.x); 4039 r[i].origin.x);
4040 }
4041 ns_reset_clipping (s->f);
4066 } 4042 }
4067 ns_unfocus (s->f);
4068 s->background_filled_p = 1; 4043 s->background_filled_p = 1;
4069 } 4044 }
4070} 4045}
@@ -4214,9 +4189,11 @@ ns_draw_glyph_string (struct glyph_string *s)
4214 if (next->first_glyph->type != STRETCH_GLYPH) 4189 if (next->first_glyph->type != STRETCH_GLYPH)
4215 { 4190 {
4216 n = ns_get_glyph_string_clip_rect (s->next, r); 4191 n = ns_get_glyph_string_clip_rect (s->next, r);
4217 ns_focus (s->f, r, n); 4192 if (ns_clip_to_rect (s->f, r, n))
4218 ns_maybe_dumpglyphs_background (s->next, 1); 4193 {
4219 ns_unfocus (s->f); 4194 ns_maybe_dumpglyphs_background (s->next, 1);
4195 ns_reset_clipping (s->f);
4196 }
4220 } 4197 }
4221 else 4198 else
4222 { 4199 {
@@ -4231,10 +4208,12 @@ ns_draw_glyph_string (struct glyph_string *s)
4231 || s->first_glyph->type == COMPOSITE_GLYPH)) 4208 || s->first_glyph->type == COMPOSITE_GLYPH))
4232 { 4209 {
4233 n = ns_get_glyph_string_clip_rect (s, r); 4210 n = ns_get_glyph_string_clip_rect (s, r);
4234 ns_focus (s->f, r, n); 4211 if (ns_clip_to_rect (s->f, r, n))
4235 ns_maybe_dumpglyphs_background (s, 1); 4212 {
4236 ns_dumpglyphs_box_or_relief (s); 4213 ns_maybe_dumpglyphs_background (s, 1);
4237 ns_unfocus (s->f); 4214 ns_dumpglyphs_box_or_relief (s);
4215 ns_reset_clipping (s->f);
4216 }
4238 box_drawn_p = 1; 4217 box_drawn_p = 1;
4239 } 4218 }
4240 4219
@@ -4243,9 +4222,11 @@ ns_draw_glyph_string (struct glyph_string *s)
4243 4222
4244 case IMAGE_GLYPH: 4223 case IMAGE_GLYPH:
4245 n = ns_get_glyph_string_clip_rect (s, r); 4224 n = ns_get_glyph_string_clip_rect (s, r);
4246 ns_focus (s->f, r, n); 4225 if (ns_clip_to_rect (s->f, r, n))
4247 ns_dumpglyphs_image (s, r[0]); 4226 {
4248 ns_unfocus (s->f); 4227 ns_dumpglyphs_image (s, r[0]);
4228 ns_reset_clipping (s->f);
4229 }
4249 break; 4230 break;
4250 4231
4251 case STRETCH_GLYPH: 4232 case STRETCH_GLYPH:
@@ -4255,66 +4236,68 @@ ns_draw_glyph_string (struct glyph_string *s)
4255 case CHAR_GLYPH: 4236 case CHAR_GLYPH:
4256 case COMPOSITE_GLYPH: 4237 case COMPOSITE_GLYPH:
4257 n = ns_get_glyph_string_clip_rect (s, r); 4238 n = ns_get_glyph_string_clip_rect (s, r);
4258 ns_focus (s->f, r, n); 4239 if (ns_clip_to_rect (s->f, r, n))
4240 {
4241 if (s->for_overlaps || (s->cmp_from > 0
4242 && ! s->first_glyph->u.cmp.automatic))
4243 s->background_filled_p = 1;
4244 else
4245 ns_maybe_dumpglyphs_background
4246 (s, s->first_glyph->type == COMPOSITE_GLYPH);
4259 4247
4260 if (s->for_overlaps || (s->cmp_from > 0 4248 if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR)
4261 && ! s->first_glyph->u.cmp.automatic)) 4249 {
4262 s->background_filled_p = 1; 4250 unsigned long tmp = NS_FACE_BACKGROUND (s->face);
4263 else 4251 NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face);
4264 ns_maybe_dumpglyphs_background 4252 NS_FACE_FOREGROUND (s->face) = tmp;
4265 (s, s->first_glyph->type == COMPOSITE_GLYPH); 4253 }
4266 4254
4267 if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR) 4255 {
4268 { 4256 BOOL isComposite = s->first_glyph->type == COMPOSITE_GLYPH;
4269 unsigned long tmp = NS_FACE_BACKGROUND (s->face);
4270 NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face);
4271 NS_FACE_FOREGROUND (s->face) = tmp;
4272 }
4273 4257
4274 { 4258 if (isComposite)
4275 BOOL isComposite = s->first_glyph->type == COMPOSITE_GLYPH; 4259 ns_draw_composite_glyph_string_foreground (s);
4260 else
4261 ns_draw_glyph_string_foreground (s);
4262 }
4276 4263
4277 if (isComposite) 4264 {
4278 ns_draw_composite_glyph_string_foreground (s); 4265 NSColor *col = (NS_FACE_FOREGROUND (s->face) != 0
4279 else 4266 ? ns_lookup_indexed_color (NS_FACE_FOREGROUND (s->face),
4280 ns_draw_glyph_string_foreground (s); 4267 s->f)
4281 } 4268 : FRAME_FOREGROUND_COLOR (s->f));
4269 [col set];
4270
4271 /* Draw underline, overline, strike-through. */
4272 ns_draw_text_decoration (s, s->face, col, s->width, s->x);
4273 }
4282 4274
4283 { 4275 if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR)
4284 NSColor *col = (NS_FACE_FOREGROUND (s->face) != 0 4276 {
4285 ? ns_lookup_indexed_color (NS_FACE_FOREGROUND (s->face), 4277 unsigned long tmp = NS_FACE_BACKGROUND (s->face);
4286 s->f) 4278 NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face);
4287 : FRAME_FOREGROUND_COLOR (s->f)); 4279 NS_FACE_FOREGROUND (s->face) = tmp;
4288 [col set]; 4280 }
4289
4290 /* Draw underline, overline, strike-through. */
4291 ns_draw_text_decoration (s, s->face, col, s->width, s->x);
4292 }
4293 4281
4294 if (s->hl == DRAW_CURSOR && s->w->phys_cursor_type == FILLED_BOX_CURSOR) 4282 ns_reset_clipping (s->f);
4295 {
4296 unsigned long tmp = NS_FACE_BACKGROUND (s->face);
4297 NS_FACE_BACKGROUND (s->face) = NS_FACE_FOREGROUND (s->face);
4298 NS_FACE_FOREGROUND (s->face) = tmp;
4299 } 4283 }
4300
4301 ns_unfocus (s->f);
4302 break; 4284 break;
4303 4285
4304 case GLYPHLESS_GLYPH: 4286 case GLYPHLESS_GLYPH:
4305 n = ns_get_glyph_string_clip_rect (s, r); 4287 n = ns_get_glyph_string_clip_rect (s, r);
4306 ns_focus (s->f, r, n); 4288 if (ns_clip_to_rect (s->f, r, n))
4307 4289 {
4308 if (s->for_overlaps || (s->cmp_from > 0 4290 if (s->for_overlaps || (s->cmp_from > 0
4309 && ! s->first_glyph->u.cmp.automatic)) 4291 && ! s->first_glyph->u.cmp.automatic))
4310 s->background_filled_p = 1; 4292 s->background_filled_p = 1;
4311 else 4293 else
4312 ns_maybe_dumpglyphs_background 4294 ns_maybe_dumpglyphs_background
4313 (s, s->first_glyph->type == COMPOSITE_GLYPH); 4295 (s, s->first_glyph->type == COMPOSITE_GLYPH);
4314 /* ... */ 4296 /* ... */
4315 /* Not yet implemented. */ 4297 /* Not yet implemented. */
4316 /* ... */ 4298 /* ... */
4317 ns_unfocus (s->f); 4299 ns_reset_clipping (s->f);
4300 }
4318 break; 4301 break;
4319 4302
4320 default: 4303 default:
@@ -4325,9 +4308,11 @@ ns_draw_glyph_string (struct glyph_string *s)
4325 if (!s->for_overlaps && !box_drawn_p && s->face->box != FACE_NO_BOX) 4308 if (!s->for_overlaps && !box_drawn_p && s->face->box != FACE_NO_BOX)
4326 { 4309 {
4327 n = ns_get_glyph_string_clip_rect (s, r); 4310 n = ns_get_glyph_string_clip_rect (s, r);
4328 ns_focus (s->f, r, n); 4311 if (ns_clip_to_rect (s->f, r, n))
4329 ns_dumpglyphs_box_or_relief (s); 4312 {
4330 ns_unfocus (s->f); 4313 ns_dumpglyphs_box_or_relief (s);
4314 ns_reset_clipping (s->f);
4315 }
4331 } 4316 }
4332 4317
4333 s->num_clips = 0; 4318 s->num_clips = 0;
@@ -5133,7 +5118,7 @@ static struct redisplay_interface ns_redisplay_interface =
5133 ns_after_update_window_line, 5118 ns_after_update_window_line,
5134 ns_update_window_begin, 5119 ns_update_window_begin,
5135 ns_update_window_end, 5120 ns_update_window_end,
5136 0, /* flush_display */ 5121 ns_flush_display, /* flush_display */
5137 x_clear_window_mouse_face, 5122 x_clear_window_mouse_face,
5138 x_get_glyph_overhangs, 5123 x_get_glyph_overhangs,
5139 x_fix_overlapping_area, 5124 x_fix_overlapping_area,
@@ -5350,7 +5335,21 @@ ns_term_init (Lisp_Object display_name)
5350 alpha: 1.0] 5335 alpha: 1.0]
5351 forKey: [NSString stringWithUTF8String: name]]; 5336 forKey: [NSString stringWithUTF8String: name]];
5352 } 5337 }
5353 [cl writeToFile: nil]; 5338
5339 /* FIXME: Report any errors writing the color file below. */
5340#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
5341#if MAC_OS_X_VERSION_MIN_REQUIRED < 101100
5342 if ([cl respondsToSelector:@selector(writeToURL:error:)])
5343#endif
5344 [cl writeToURL:nil error:nil];
5345#if MAC_OS_X_VERSION_MIN_REQUIRED < 101100
5346 else
5347#endif
5348#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 101100 */
5349#if MAC_OS_X_VERSION_MIN_REQUIRED < 101100 \
5350 || defined (NS_IMPL_GNUSTEP)
5351 [cl writeToFile: nil];
5352#endif
5354 } 5353 }
5355 } 5354 }
5356 5355