aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Reitter2008-08-20 17:46:37 +0000
committerDavid Reitter2008-08-20 17:46:37 +0000
commit595d6a93bfcb03abb6c660c2adbe45ba8f9e14a3 (patch)
treea83b4fd4ae01796e74fe59cd8d8b819deb93e82d /src
parent06197b17cd70c30efd518a3d93f193bb1c4753b5 (diff)
downloademacs-595d6a93bfcb03abb6c660c2adbe45ba8f9e14a3.tar.gz
emacs-595d6a93bfcb03abb6c660c2adbe45ba8f9e14a3.zip
Clear cursor properly rather than redrawing the area. Respect width of
bar cursors. remove ns-specific code for cursor blinking.
Diffstat (limited to 'src')
-rw-r--r--src/nsterm.m275
1 files changed, 125 insertions, 150 deletions
diff --git a/src/nsterm.m b/src/nsterm.m
index 3fb9905e4b7..561a9b62883 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -168,13 +168,6 @@ Lisp_Object ns_control_modifier;
168 the Function modifer (laptops). May be any of the modifier lisp symbols. */ 168 the Function modifer (laptops). May be any of the modifier lisp symbols. */
169Lisp_Object ns_function_modifier; 169Lisp_Object ns_function_modifier;
170 170
171/* A floating point value specifying the rate at which to blink the cursor.
172 YES indicates 0.5, NO indicates no blinking. */
173Lisp_Object ns_cursor_blink_rate;
174
175/* Used for liason with core emacs cursor-blink-mode. */
176Lisp_Object ns_cursor_blink_mode;
177
178/* A floating point value specifying vertical stretch (positive) or shrink 171/* A floating point value specifying vertical stretch (positive) or shrink
179 (negative) of text line spacing. Zero means default spacing. 172 (negative) of text line spacing. Zero means default spacing.
180 YES indicates 0.5, NO indicates 0.0. */ 173 YES indicates 0.5, NO indicates 0.0. */
@@ -235,7 +228,6 @@ static BOOL send_appdefined = YES;
235static NSEvent *last_appdefined_event = 0; 228static NSEvent *last_appdefined_event = 0;
236static NSTimer *timed_entry = 0; 229static NSTimer *timed_entry = 0;
237static NSTimer *fd_entry = nil; 230static NSTimer *fd_entry = nil;
238static NSTimer *cursor_blink_entry = nil;
239static NSTimer *scroll_repeat_entry = nil; 231static NSTimer *scroll_repeat_entry = nil;
240static fd_set select_readfds, t_readfds; 232static fd_set select_readfds, t_readfds;
241static struct timeval select_timeout; 233static struct timeval select_timeout;
@@ -2270,6 +2262,10 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
2270 int on_p, int active_p) 2262 int on_p, int active_p)
2271/* -------------------------------------------------------------------------- 2263/* --------------------------------------------------------------------------
2272 External call (RIF): draw cursor 2264 External call (RIF): draw cursor
2265 (modeled after x_draw_window_cursor and erase_phys_cursor.
2266 FIXME: erase_phys_cursor is called from display_and_set_cursor,
2267 called from update_window_cursor/x_update_window_end/...
2268 Why do we have to duplicate this code?
2273 -------------------------------------------------------------------------- */ 2269 -------------------------------------------------------------------------- */
2274{ 2270{
2275 NSRect r, s; 2271 NSRect r, s;
@@ -2278,14 +2274,23 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
2278 struct glyph *phys_cursor_glyph; 2274 struct glyph *phys_cursor_glyph;
2279 int overspill; 2275 int overspill;
2280 unsigned char drawGlyph = 0, cursorType, oldCursorType; 2276 unsigned char drawGlyph = 0, cursorType, oldCursorType;
2277 int new_cursor_type;
2278 int new_cursor_width;
2279 int active_cursor;
2280 enum draw_glyphs_face hl;
2281 struct glyph_matrix *active_glyphs = w->current_matrix;
2282 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2283 int hpos = w->phys_cursor.hpos;
2284 int vpos = w->phys_cursor.vpos;
2285 struct glyph_row *cursor_row;
2281 2286
2282 NSTRACE (dumpcursor); 2287 NSTRACE (dumpcursor);
2283 2288
2284 if (!on_p) 2289 if (!on_p) // check this? && !w->phys_cursor_on_p)
2285 return; 2290 return;
2286 2291
2287 w->phys_cursor_type = cursor_type; 2292 w->phys_cursor_type = cursor_type;
2288 w->phys_cursor_on_p = 1; 2293 w->phys_cursor_on_p = on_p;
2289 2294
2290 if (cursor_type == NO_CURSOR) 2295 if (cursor_type == NO_CURSOR)
2291 { 2296 {
@@ -2318,9 +2323,10 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
2318 if (overspill > 0) 2323 if (overspill > 0)
2319 r.size.width -= overspill; 2324 r.size.width -= overspill;
2320 2325
2321 /* TODO: 23: use emacs stored f->cursor_type instead of ns-specific */
2322 oldCursorType = FRAME_CURSOR (f); 2326 oldCursorType = FRAME_CURSOR (f);
2323 cursorType = FRAME_CURSOR (f) = FRAME_NEW_CURSOR (f); 2327 cursorType = FRAME_CURSOR (f) = FRAME_NEW_CURSOR (f);
2328
2329 /* TODO: 23: use emacs stored cursor color instead of ns-specific */
2324 f->output_data.ns->current_cursor_color 2330 f->output_data.ns->current_cursor_color
2325 = f->output_data.ns->desired_cursor_color; 2331 = f->output_data.ns->desired_cursor_color;
2326 2332
@@ -2342,51 +2348,125 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row,
2342 if (cursorType == no_highlight || cursor_type == NO_CURSOR) 2348 if (cursorType == no_highlight || cursor_type == NO_CURSOR)
2343 { 2349 {
2344 /* clearing for blink: erase the cursor itself */ 2350 /* clearing for blink: erase the cursor itself */
2351
2352 /* No cursor displayed or row invalidated => nothing to do on the
2353 screen. */
2354 if (w->phys_cursor_type == NO_CURSOR)
2355 return;
2356
2357 /* VPOS >= active_glyphs->nrows means that window has been resized.
2358 Don't bother to erase the cursor. */
2359 if (vpos >= active_glyphs->nrows)
2360 return;
2361
2362 /* If row containing cursor is marked invalid, there is nothing we
2363 can do. */
2364 cursor_row = MATRIX_ROW (active_glyphs, vpos);
2365 if (!cursor_row->enabled_p)
2366 return;
2367
2368 /* If line spacing is > 0, old cursor may only be partially visible in
2369 window after split-window. So adjust visible height. */
2370 cursor_row->visible_height = min (cursor_row->visible_height,
2371 window_text_bottom_y (w) - cursor_row->y);
2372
2373 /* If row is completely invisible, don't attempt to delete a cursor which
2374 isn't there. This can happen if cursor is at top of a window, and
2375 we switch to a buffer with a header line in that window. */
2376 if (cursor_row->visible_height <= 0)
2377 return;
2378
2379 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
2380 if (cursor_row->cursor_in_fringe_p)
2381 {
2382 cursor_row->cursor_in_fringe_p = 0;
2383 draw_fringe_bitmap (w, cursor_row, 0);
2384 return;
2385 }
2386
2387 /* This can happen when the new row is shorter than the old one.
2388 In this case, either draw_glyphs or clear_end_of_line
2389 should have cleared the cursor. Note that we wouldn't be
2390 able to erase the cursor in this case because we don't have a
2391 cursor glyph at hand. */
2392 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
2393 return;
2394
2395 /* If the cursor is in the mouse face area, redisplay that when
2396 we clear the cursor. */
2397 if (! NILP (dpyinfo->mouse_face_window)
2398 && w == XWINDOW (dpyinfo->mouse_face_window)
2399 && (vpos > dpyinfo->mouse_face_beg_row
2400 || (vpos == dpyinfo->mouse_face_beg_row
2401 && hpos >= dpyinfo->mouse_face_beg_col))
2402 && (vpos < dpyinfo->mouse_face_end_row
2403 || (vpos == dpyinfo->mouse_face_end_row
2404 && hpos < dpyinfo->mouse_face_end_col))
2405 /* Don't redraw the cursor's spot in mouse face if it is at the
2406 end of a line (on a newline). The cursor appears there, but
2407 mouse highlighting does not. */
2408 && cursor_row->used[TEXT_AREA] > hpos)
2409 hl = DRAW_MOUSE_FACE;
2410 else
2411 hl = DRAW_NORMAL_TEXT;
2412 drawGlyph = 1; // just draw the Glyph
2345 [FRAME_BACKGROUND_COLOR (f) set]; 2413 [FRAME_BACKGROUND_COLOR (f) set];
2346 cursorType = oldCursorType; /* just clear what we had before */ 2414
2415 NSDisableScreenUpdates ();
2347 } 2416 }
2348 else 2417 else
2418 {
2419 cursorType = cursor_type;
2420 hl = DRAW_CURSOR;
2349 [FRAME_CURSOR_COLOR (f) set]; 2421 [FRAME_CURSOR_COLOR (f) set];
2422
2350 2423
2351 if (!active_p) 2424 if (!active_p)
2352 { 2425 {
2353 /* inactive window: ignore what we just set and use a hollow box */ 2426 /* inactive window: ignore what we just set and use a hollow box */
2354 cursorType = hollow_box; 2427 cursorType = hollow_box;
2355 [FRAME_CURSOR_COLOR (f) set]; 2428 [FRAME_CURSOR_COLOR (f) set];
2356 } 2429 }
2357 2430
2358 switch (cursorType) 2431 NSDisableScreenUpdates ();
2359 { 2432
2360 case no_highlight: 2433 switch (cursorType)
2361 break; 2434 {
2362 case filled_box: 2435 case NO_CURSOR: // no_highlight:
2363 NSRectFill (r); 2436 break;
2364 drawGlyph = 1; 2437 case FILLED_BOX_CURSOR: //filled_box:
2365 break; 2438 NSRectFill (r);
2366 case hollow_box: 2439 drawGlyph = 1;
2367 NSRectFill (r); 2440 break;
2368 [FRAME_BACKGROUND_COLOR (f) set]; 2441 case HOLLOW_BOX_CURSOR: //hollow_box:
2369 NSRectFill (NSInsetRect (r, 1, 1)); 2442 NSRectFill (r);
2370 [FRAME_CURSOR_COLOR (f) set]; 2443 [FRAME_BACKGROUND_COLOR (f) set];
2371 drawGlyph = 1; 2444 NSRectFill (NSInsetRect (r, 1, 1));
2372 break; 2445 [FRAME_CURSOR_COLOR (f) set];
2373 case underscore: 2446 drawGlyph = 1;
2374 s = r; 2447 break;
2375 s.origin.y += lrint (0.75 * s.size.height); 2448 case HBAR_CURSOR: // underscore:
2376 s.size.height = lrint (s.size.height * 0.25); 2449 s = r;
2377 NSRectFill (s); 2450 s.origin.y += lrint (0.75 * s.size.height);
2378 break; 2451 s.size.height = cursor_width; //lrint (s.size.height * 0.25);
2379 case bar: 2452 NSRectFill (s);
2380 s = r; 2453 break;
2381 s.size.width = 1; 2454 case BAR_CURSOR: //bar:
2382 NSRectFill (s); 2455 s = r;
2383 break; 2456 s.size.width = cursor_width;
2457 NSRectFill (s);
2458 drawGlyph = 1;
2459 break;
2460 }
2384 } 2461 }
2385 ns_unfocus (f); 2462 ns_unfocus (f);
2386 2463
2387 /* if needed, draw the character under the cursor */ 2464 /* if needed, draw the character under the cursor */
2388 if (drawGlyph) 2465 if (drawGlyph)
2389 draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); 2466 draw_phys_cursor_glyph (w, glyph_row, hl);
2467
2468 NSEnableScreenUpdates ();
2469
2390} 2470}
2391 2471
2392 2472
@@ -3173,35 +3253,6 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds,
3173 repeats: YES] 3253 repeats: YES]
3174 retain]; 3254 retain];
3175 3255
3176 if (!NILP (ns_cursor_blink_mode) && !cursor_blink_entry)
3177 {
3178 if (!NUMBERP (ns_cursor_blink_rate))
3179 ns_cursor_blink_rate = make_float (0.5);
3180 cursor_blink_entry = [[NSTimer
3181 scheduledTimerWithTimeInterval: XFLOATINT (ns_cursor_blink_rate)
3182 target: NSApp
3183 selector: @selector (cursor_blink_handler:)
3184 userInfo: 0
3185 repeats: YES]
3186 retain];
3187 }
3188 else if (NILP (ns_cursor_blink_mode) && cursor_blink_entry)
3189 {
3190 if (NUMBERP (ns_cursor_blink_rate))
3191 ns_cursor_blink_rate = Qnil;
3192 struct ns_display_info *dpyinfo = x_display_list; /* HACK */
3193 [cursor_blink_entry invalidate];
3194 [cursor_blink_entry release];
3195 cursor_blink_entry = 0;
3196 if (dpyinfo->x_highlight_frame)
3197 {
3198 Lisp_Object tem
3199 = get_frame_param (dpyinfo->x_highlight_frame, Qcursor_type);
3200 dpyinfo->x_highlight_frame->output_data.ns->desired_cursor
3201 = ns_lisp_to_cursor_type (tem);
3202 }
3203 }
3204
3205 /* Let Application dispatch events until it receives an event of the type 3256 /* Let Application dispatch events until it receives an event of the type
3206 NX_APPDEFINED, which should only be sent by timeout_handler. */ 3257 NX_APPDEFINED, which should only be sent by timeout_handler. */
3207 inNsSelect = 1; 3258 inNsSelect = 1;
@@ -3487,8 +3538,6 @@ ns_set_default_prefs ()
3487 ns_command_modifier = Qsuper; 3538 ns_command_modifier = Qsuper;
3488 ns_control_modifier = Qcontrol; 3539 ns_control_modifier = Qcontrol;
3489 ns_function_modifier = Qnone; 3540 ns_function_modifier = Qnone;
3490 ns_cursor_blink_rate = Qnil;
3491 ns_cursor_blink_mode = Qnil;
3492 ns_expand_space = make_float (0.0); 3541 ns_expand_space = make_float (0.0);
3493 ns_antialias_text = Qt; 3542 ns_antialias_text = Qt;
3494 ns_antialias_threshold = 10.0; /* not exposed to lisp side */ 3543 ns_antialias_threshold = 10.0; /* not exposed to lisp side */
@@ -3795,10 +3844,6 @@ ns_term_init (Lisp_Object display_name)
3795 Qnil, Qnil, NO, YES); 3844 Qnil, Qnil, NO, YES);
3796 if (NILP (ns_function_modifier)) 3845 if (NILP (ns_function_modifier))
3797 ns_function_modifier = Qnone; 3846 ns_function_modifier = Qnone;
3798 ns_default ("CursorBlinkRate", &ns_cursor_blink_rate,
3799 make_float (0.5), Qnil, YES, NO);
3800 if (NUMBERP (ns_cursor_blink_rate))
3801 ns_cursor_blink_mode = Qt;
3802 ns_default ("ExpandSpace", &ns_expand_space, 3847 ns_default ("ExpandSpace", &ns_expand_space,
3803 make_float (0.5), make_float (0.0), YES, NO); 3848 make_float (0.5), make_float (0.0), YES, NO);
3804 ns_default ("GSFontAntiAlias", &ns_antialias_text, 3849 ns_default ("GSFontAntiAlias", &ns_antialias_text,
@@ -4194,31 +4239,6 @@ fprintf (stderr, "res = %d\n", EQ (res, Qt)); /* FIXME */
4194 4239
4195extern void update_window_cursor (struct window *w, int on); 4240extern void update_window_cursor (struct window *w, int on);
4196 4241
4197- (void)cursor_blink_handler: (NSTimer *)cursorEntry
4198/* --------------------------------------------------------------------------
4199 Flash the cursor
4200 -------------------------------------------------------------------------- */
4201{
4202 struct ns_display_info *dpyinfo = x_display_list; /*HACK, but OK for now */
4203 struct frame *f = dpyinfo->x_highlight_frame;
4204 NSTRACE (cursor_blink_handler);
4205
4206 if (!f)
4207 return;
4208 if (f->output_data.ns->current_cursor == no_highlight)
4209 {
4210 Lisp_Object tem = get_frame_param (f, Qcursor_type);
4211 f->output_data.ns->desired_cursor = ns_lisp_to_cursor_type (tem);
4212 }
4213 else
4214 {
4215 f->output_data.ns->desired_cursor = no_highlight;
4216 }
4217 update_window_cursor (XWINDOW (FRAME_SELECTED_WINDOW (f)), 1);
4218 /*x_update_cursor (f, 1); */
4219}
4220
4221
4222- (void)fd_handler: (NSTimer *) fdEntry 4242- (void)fd_handler: (NSTimer *) fdEntry
4223/* -------------------------------------------------------------------------- 4243/* --------------------------------------------------------------------------
4224 Check data waiting on file descriptors and terminate if so 4244 Check data waiting on file descriptors and terminate if so
@@ -6025,15 +6045,12 @@ static void selectItemWithTag (NSPopUpButton *popup, int tag)
6025 int cursorType 6045 int cursorType
6026 = ns_lisp_to_cursor_type (get_frame_param (frame, Qcursor_type)); 6046 = ns_lisp_to_cursor_type (get_frame_param (frame, Qcursor_type));
6027 prevExpandSpace = XFLOATINT (ns_expand_space); 6047 prevExpandSpace = XFLOATINT (ns_expand_space);
6028 prevBlinkRate = NILP (ns_cursor_blink_rate)
6029 ? 0 : XFLOATINT (ns_cursor_blink_rate);
6030 6048
6031#ifdef NS_IMPL_COCOA 6049#ifdef NS_IMPL_COCOA
6032 prevUseHighlightColor = ns_use_system_highlight_color; 6050 prevUseHighlightColor = ns_use_system_highlight_color;
6033#endif 6051#endif
6034 6052
6035 [expandSpaceSlider setFloatValue: prevExpandSpace]; 6053 [expandSpaceSlider setFloatValue: prevExpandSpace];
6036 [cursorBlinkSlider setFloatValue: prevBlinkRate];
6037 [cursorTypeMatrix selectCellWithTag: (cursorType == filled_box ? 1 : 6054 [cursorTypeMatrix selectCellWithTag: (cursorType == filled_box ? 1 :
6038 (cursorType == bar ? 2 : 6055 (cursorType == bar ? 2 :
6039 (cursorType == underscore ? 3 : 4)))]; 6056 (cursorType == underscore ? 3 : 4)))];
@@ -6062,9 +6079,7 @@ static void selectItemWithTag (NSPopUpButton *popup, int tag)
6062 int ctrlTag = [[controlModMenu selectedItem] tag]; 6079 int ctrlTag = [[controlModMenu selectedItem] tag];
6063 int fnTag = [[functionModMenu selectedItem] tag]; 6080 int fnTag = [[functionModMenu selectedItem] tag];
6064#endif 6081#endif
6065 float blinkRate = [cursorBlinkSlider floatValue];
6066 float expandSpace = [expandSpaceSlider floatValue]; 6082 float expandSpace = [expandSpaceSlider floatValue];
6067 Lisp_Object old_cursor_blink_mode;
6068 6083
6069 if (expandSpace != prevExpandSpace) 6084 if (expandSpace != prevExpandSpace)
6070 { 6085 {
@@ -6075,38 +6090,6 @@ static void selectItemWithTag (NSPopUpButton *popup, int tag)
6075 x_set_window_size (frame, 0, frame->text_cols, frame->text_lines); */ 6090 x_set_window_size (frame, 0, frame->text_cols, frame->text_lines); */
6076 prevExpandSpace = expandSpace; 6091 prevExpandSpace = expandSpace;
6077 } 6092 }
6078 if (blinkRate != prevBlinkRate)
6079 {
6080 old_cursor_blink_mode = ns_cursor_blink_mode;
6081 if (blinkRate == 0.0)
6082 {
6083 ns_cursor_blink_rate = Qnil;
6084 ns_cursor_blink_mode = Qnil;
6085 }
6086 else
6087 {
6088 ns_cursor_blink_rate = make_float (blinkRate);
6089 ns_cursor_blink_mode = Qt;
6090 }
6091 if (!EQ (ns_cursor_blink_mode, old_cursor_blink_mode))
6092 Feval (Fcons (intern ("blink-cursor-mode"), Qnil));
6093
6094 if (blinkRate != 0.0 && prevBlinkRate != 0.0)
6095 { /* if changed rates, remove blink handler so change picked up */
6096 struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (frame);
6097 [cursor_blink_entry invalidate];
6098 [cursor_blink_entry release];
6099 cursor_blink_entry = 0;
6100 if (dpyinfo->x_highlight_frame)
6101 {
6102 Lisp_Object tem
6103 = get_frame_param (dpyinfo->x_highlight_frame, Qcursor_type);
6104 dpyinfo->x_highlight_frame->output_data.ns->desired_cursor
6105 = ns_lisp_to_cursor_type (tem);
6106 }
6107 }
6108 prevBlinkRate = blinkRate;
6109 }
6110 FRAME_NEW_CURSOR (frame) 6093 FRAME_NEW_CURSOR (frame)
6111 = (cursorTag == 1 ? filled_box 6094 = (cursorTag == 1 ? filled_box
6112 : cursorTag == 2 ? bar 6095 : cursorTag == 2 ? bar
@@ -6419,14 +6402,6 @@ Set to control, meta, alt, super, or hyper means it is taken to be that key.\n\
6419Set to none means that the function key is not interpreted by Emacs at all,\n\ 6402Set to none means that the function key is not interpreted by Emacs at all,\n\
6420allowing it to be used at a lower level for accented character entry."); 6403allowing it to be used at a lower level for accented character entry.");
6421 6404
6422 DEFVAR_LISP ("ns-cursor-blink-rate", &ns_cursor_blink_rate,
6423 "Rate at which the Emacs cursor blinks (in seconds).\n\
6424Set to nil to disable blinking.");
6425
6426 DEFVAR_LISP ("ns-cursor-blink-mode", &ns_cursor_blink_mode,
6427 "Internal variable -- use M-x blink-cursor-mode or preferences\n\
6428panel to control this setting.");
6429
6430 DEFVAR_LISP ("ns-expand-space", &ns_expand_space, 6405 DEFVAR_LISP ("ns-expand-space", &ns_expand_space,
6431 "Amount by which spacing between lines is expanded (positive)\n\ 6406 "Amount by which spacing between lines is expanded (positive)\n\
6432or shrunk (negative). Zero (the default) means standard line height.\n\ 6407or shrunk (negative). Zero (the default) means standard line height.\n\