diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/xdisp.c | 241 |
1 files changed, 235 insertions, 6 deletions
diff --git a/src/xdisp.c b/src/xdisp.c index 477fb623ad5..e7656d43077 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -227,6 +227,9 @@ Lisp_Object Qgrow_only; | |||
| 227 | Lisp_Object Qinhibit_eval_during_redisplay; | 227 | Lisp_Object Qinhibit_eval_during_redisplay; |
| 228 | Lisp_Object Qbuffer_position, Qposition, Qobject; | 228 | Lisp_Object Qbuffer_position, Qposition, Qobject; |
| 229 | 229 | ||
| 230 | /* Cursor shapes */ | ||
| 231 | Lisp_Object Qbar, Qhbar, Qbox, Qhollow; | ||
| 232 | |||
| 230 | Lisp_Object Qrisky_local_variable; | 233 | Lisp_Object Qrisky_local_variable; |
| 231 | 234 | ||
| 232 | /* Holds the list (error). */ | 235 | /* Holds the list (error). */ |
| @@ -531,9 +534,19 @@ static int message_cleared_p; | |||
| 531 | /* Non-zero means we want a hollow cursor in windows that are not | 534 | /* Non-zero means we want a hollow cursor in windows that are not |
| 532 | selected. Zero means there's no cursor in such windows. */ | 535 | selected. Zero means there's no cursor in such windows. */ |
| 533 | 536 | ||
| 534 | int cursor_in_non_selected_windows; | 537 | Lisp_Object Vcursor_in_non_selected_windows; |
| 535 | Lisp_Object Qcursor_in_non_selected_windows; | 538 | Lisp_Object Qcursor_in_non_selected_windows; |
| 536 | 539 | ||
| 540 | /* Specifies the desired cursor-type to use to show the blinking | ||
| 541 | cursor off state and cursor shown in non-selected windows. | ||
| 542 | t means to use the default. */ | ||
| 543 | |||
| 544 | Lisp_Object Valternate_cursor_type; | ||
| 545 | Lisp_Object Qalternate_cursor_type; | ||
| 546 | |||
| 547 | /* How to blink the default frame cursor off. */ | ||
| 548 | Lisp_Object Vblink_cursor_alist; | ||
| 549 | |||
| 537 | /* A scratch glyph row with contents used for generating truncation | 550 | /* A scratch glyph row with contents used for generating truncation |
| 538 | glyphs. Also used in direct_output_for_insert. */ | 551 | glyphs. Also used in direct_output_for_insert. */ |
| 539 | 552 | ||
| @@ -15194,6 +15207,199 @@ invisible_p (propval, list) | |||
| 15194 | 15207 | ||
| 15195 | 15208 | ||
| 15196 | /*********************************************************************** | 15209 | /*********************************************************************** |
| 15210 | Cursor types | ||
| 15211 | ***********************************************************************/ | ||
| 15212 | |||
| 15213 | /* Value is the internal representation of the specified cursor type | ||
| 15214 | ARG. If type is BAR_CURSOR, return in *WIDTH the specified width | ||
| 15215 | of the bar cursor. */ | ||
| 15216 | |||
| 15217 | enum text_cursor_kinds | ||
| 15218 | get_specified_cursor_type (arg, width) | ||
| 15219 | Lisp_Object arg; | ||
| 15220 | int *width; | ||
| 15221 | { | ||
| 15222 | enum text_cursor_kinds type; | ||
| 15223 | |||
| 15224 | if (NILP (arg)) | ||
| 15225 | return NO_CURSOR; | ||
| 15226 | |||
| 15227 | if (EQ (arg, Qbox)) | ||
| 15228 | return FILLED_BOX_CURSOR; | ||
| 15229 | |||
| 15230 | if (EQ (arg, Qhollow)) | ||
| 15231 | return HOLLOW_BOX_CURSOR; | ||
| 15232 | |||
| 15233 | if (EQ (arg, Qbar)) | ||
| 15234 | { | ||
| 15235 | *width = 2; | ||
| 15236 | return BAR_CURSOR; | ||
| 15237 | } | ||
| 15238 | |||
| 15239 | if (CONSP (arg) | ||
| 15240 | && EQ (XCAR (arg), Qbar) | ||
| 15241 | && INTEGERP (XCDR (arg)) | ||
| 15242 | && XINT (XCDR (arg)) >= 0) | ||
| 15243 | { | ||
| 15244 | *width = XINT (XCDR (arg)); | ||
| 15245 | return BAR_CURSOR; | ||
| 15246 | } | ||
| 15247 | |||
| 15248 | if (EQ (arg, Qhbar)) | ||
| 15249 | { | ||
| 15250 | *width = 2; | ||
| 15251 | return HBAR_CURSOR; | ||
| 15252 | } | ||
| 15253 | |||
| 15254 | if (CONSP (arg) | ||
| 15255 | && EQ (XCAR (arg), Qhbar) | ||
| 15256 | && INTEGERP (XCDR (arg)) | ||
| 15257 | && XINT (XCDR (arg)) >= 0) | ||
| 15258 | { | ||
| 15259 | *width = XINT (XCDR (arg)); | ||
| 15260 | return HBAR_CURSOR; | ||
| 15261 | } | ||
| 15262 | |||
| 15263 | /* Treat anything unknown as "hollow box cursor". | ||
| 15264 | It was bad to signal an error; people have trouble fixing | ||
| 15265 | .Xdefaults with Emacs, when it has something bad in it. */ | ||
| 15266 | type = HOLLOW_BOX_CURSOR; | ||
| 15267 | |||
| 15268 | return type; | ||
| 15269 | } | ||
| 15270 | |||
| 15271 | /* Set the default cursor types for specified frame. */ | ||
| 15272 | void | ||
| 15273 | set_frame_cursor_types (f, arg) | ||
| 15274 | struct frame *f; | ||
| 15275 | Lisp_Object arg; | ||
| 15276 | { | ||
| 15277 | int width; | ||
| 15278 | Lisp_Object tem; | ||
| 15279 | |||
| 15280 | FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width); | ||
| 15281 | FRAME_CURSOR_WIDTH (f) = width; | ||
| 15282 | |||
| 15283 | /* By default, set up the blink-off state depending on the on-state. */ | ||
| 15284 | |||
| 15285 | tem = Fassoc (arg, Vblink_cursor_alist); | ||
| 15286 | if (!NILP (tem)) | ||
| 15287 | { | ||
| 15288 | FRAME_BLINK_OFF_CURSOR (f) | ||
| 15289 | = get_specified_cursor_type (XCDR (tem), &width); | ||
| 15290 | FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width; | ||
| 15291 | } | ||
| 15292 | else | ||
| 15293 | FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR; | ||
| 15294 | } | ||
| 15295 | |||
| 15296 | |||
| 15297 | /* Return the cursor we want to be displayed. In a mini-buffer | ||
| 15298 | window, we want the cursor only to appear if we are reading input | ||
| 15299 | from this window. For the selected window, we want the cursor type | ||
| 15300 | given by the frame parameter or buffer local setting of | ||
| 15301 | cursor-type. If explicitly marked off, draw no cursor. In all | ||
| 15302 | other cases, we want a hollow box cursor. */ | ||
| 15303 | |||
| 15304 | enum text_cursor_kinds | ||
| 15305 | get_window_cursor_type (w, width) | ||
| 15306 | struct window *w; | ||
| 15307 | int *width; | ||
| 15308 | { | ||
| 15309 | struct frame *f = XFRAME (w->frame); | ||
| 15310 | struct buffer *b = XBUFFER (w->buffer); | ||
| 15311 | int cursor_type = DEFAULT_CURSOR; | ||
| 15312 | Lisp_Object alt_cursor; | ||
| 15313 | int non_selected = 0; | ||
| 15314 | |||
| 15315 | /* Echo area */ | ||
| 15316 | if (cursor_in_echo_area | ||
| 15317 | && FRAME_HAS_MINIBUF_P (f) | ||
| 15318 | && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window)) | ||
| 15319 | { | ||
| 15320 | if (w == XWINDOW (echo_area_window)) | ||
| 15321 | { | ||
| 15322 | *width = FRAME_CURSOR_WIDTH (f); | ||
| 15323 | return FRAME_DESIRED_CURSOR (f); | ||
| 15324 | } | ||
| 15325 | |||
| 15326 | non_selected = 1; | ||
| 15327 | } | ||
| 15328 | |||
| 15329 | /* Nonselected window or nonselected frame. */ | ||
| 15330 | else if (f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame | ||
| 15331 | || w != XWINDOW (f->selected_window)) | ||
| 15332 | { | ||
| 15333 | if (MINI_WINDOW_P (w) && minibuf_level == 0) | ||
| 15334 | return NO_CURSOR; | ||
| 15335 | |||
| 15336 | non_selected = 1; | ||
| 15337 | } | ||
| 15338 | |||
| 15339 | /* Never display a cursor in a window in which cursor-type is nil. */ | ||
| 15340 | if (NILP (b->cursor_type)) | ||
| 15341 | return NO_CURSOR; | ||
| 15342 | |||
| 15343 | /* Use cursor-in-non-selected-windows for non-selected window or frame. */ | ||
| 15344 | if (non_selected) | ||
| 15345 | { | ||
| 15346 | alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer); | ||
| 15347 | return get_specified_cursor_type (alt_cursor, width); | ||
| 15348 | } | ||
| 15349 | |||
| 15350 | /* Get the normal cursor type for this window. */ | ||
| 15351 | if (EQ (b->cursor_type, Qt)) | ||
| 15352 | { | ||
| 15353 | cursor_type = FRAME_DESIRED_CURSOR (f); | ||
| 15354 | *width = FRAME_CURSOR_WIDTH (f); | ||
| 15355 | } | ||
| 15356 | else | ||
| 15357 | cursor_type = get_specified_cursor_type (b->cursor_type, width); | ||
| 15358 | |||
| 15359 | /* Use normal cursor if not blinked off. */ | ||
| 15360 | if (!w->cursor_off_p) | ||
| 15361 | return cursor_type; | ||
| 15362 | |||
| 15363 | /* Cursor is blinked off, so determine how to "toggle" it. */ | ||
| 15364 | |||
| 15365 | /* First try to use alternate-cursor-type, unless it is t. */ | ||
| 15366 | alt_cursor = Fbuffer_local_value (Qalternate_cursor_type, w->buffer); | ||
| 15367 | if (!EQ (alt_cursor, Qt)) | ||
| 15368 | return get_specified_cursor_type (alt_cursor, width); | ||
| 15369 | |||
| 15370 | /* Then unless buffer's cursor-type is t (use default), | ||
| 15371 | look for an entry matching normal cursor in blink-cursor-alist. */ | ||
| 15372 | if (!EQ (b->cursor_type, Qt) && | ||
| 15373 | (alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor))) | ||
| 15374 | return get_specified_cursor_type (XCDR (alt_cursor), width); | ||
| 15375 | |||
| 15376 | /* Then see if frame has specified a specific blink off cursor type. */ | ||
| 15377 | if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR) | ||
| 15378 | { | ||
| 15379 | *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f); | ||
| 15380 | return FRAME_BLINK_OFF_CURSOR (f); | ||
| 15381 | } | ||
| 15382 | |||
| 15383 | /* Finally perform built-in cursor blinking: | ||
| 15384 | filled box <-> hollow box | ||
| 15385 | wide [h]bar <-> narrow [h]bar | ||
| 15386 | narrow [h]bar <-> no cursor | ||
| 15387 | other type <-> no cursor */ | ||
| 15388 | |||
| 15389 | if (cursor_type == FILLED_BOX_CURSOR) | ||
| 15390 | return HOLLOW_BOX_CURSOR; | ||
| 15391 | |||
| 15392 | if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1) | ||
| 15393 | { | ||
| 15394 | *width = 1; | ||
| 15395 | return cursor_type; | ||
| 15396 | } | ||
| 15397 | |||
| 15398 | return NO_CURSOR; | ||
| 15399 | } | ||
| 15400 | |||
| 15401 | |||
| 15402 | /*********************************************************************** | ||
| 15197 | Initialization | 15403 | Initialization |
| 15198 | ***********************************************************************/ | 15404 | ***********************************************************************/ |
| 15199 | 15405 | ||
| @@ -15293,6 +15499,8 @@ syms_of_xdisp () | |||
| 15293 | staticpro (&Qmessage_truncate_lines); | 15499 | staticpro (&Qmessage_truncate_lines); |
| 15294 | Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows"); | 15500 | Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows"); |
| 15295 | staticpro (&Qcursor_in_non_selected_windows); | 15501 | staticpro (&Qcursor_in_non_selected_windows); |
| 15502 | Qalternate_cursor_type = intern ("alternate-cursor-type"); | ||
| 15503 | staticpro (&Qalternate_cursor_type); | ||
| 15296 | Qgrow_only = intern ("grow-only"); | 15504 | Qgrow_only = intern ("grow-only"); |
| 15297 | staticpro (&Qgrow_only); | 15505 | staticpro (&Qgrow_only); |
| 15298 | Qinhibit_menubar_update = intern ("inhibit-menubar-update"); | 15506 | Qinhibit_menubar_update = intern ("inhibit-menubar-update"); |
| @@ -15305,6 +15513,14 @@ syms_of_xdisp () | |||
| 15305 | staticpro (&Qbuffer_position); | 15513 | staticpro (&Qbuffer_position); |
| 15306 | Qobject = intern ("object"); | 15514 | Qobject = intern ("object"); |
| 15307 | staticpro (&Qobject); | 15515 | staticpro (&Qobject); |
| 15516 | Qbar = intern ("bar"); | ||
| 15517 | staticpro (&Qbar); | ||
| 15518 | Qhbar = intern ("hbar"); | ||
| 15519 | staticpro (&Qhbar); | ||
| 15520 | Qbox = intern ("box"); | ||
| 15521 | staticpro (&Qbox); | ||
| 15522 | Qhollow = intern ("hollow"); | ||
| 15523 | staticpro (&Qhollow); | ||
| 15308 | Qrisky_local_variable = intern ("risky-local-variable"); | 15524 | Qrisky_local_variable = intern ("risky-local-variable"); |
| 15309 | staticpro (&Qrisky_local_variable); | 15525 | staticpro (&Qrisky_local_variable); |
| 15310 | Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces"); | 15526 | Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces"); |
| @@ -15515,11 +15731,24 @@ only, until their display becomes empty, at which point the windows | |||
| 15515 | go back to their normal size. */); | 15731 | go back to their normal size. */); |
| 15516 | Vresize_mini_windows = Qgrow_only; | 15732 | Vresize_mini_windows = Qgrow_only; |
| 15517 | 15733 | ||
| 15518 | DEFVAR_BOOL ("cursor-in-non-selected-windows", | 15734 | DEFVAR_LISP ("cursor-in-non-selected-windows", |
| 15519 | &cursor_in_non_selected_windows, | 15735 | &Vcursor_in_non_selected_windows, |
| 15520 | doc: /* *Non-nil means display a hollow cursor in non-selected windows. | 15736 | doc: /* *Cursor type to display in non-selected windows. |
| 15521 | nil means don't display a cursor there. */); | 15737 | t means to use hollow box cursor. See `cursor-type' for other values. */); |
| 15522 | cursor_in_non_selected_windows = 1; | 15738 | Vcursor_in_non_selected_windows = Qt; |
| 15739 | |||
| 15740 | DEFVAR_LISP ("alternate-cursor-type", &Valternate_cursor_type, | ||
| 15741 | doc: /* *Cursor type displayed in the blinking cursor off state. | ||
| 15742 | t means to use default. See `cursor-type' for other values. */); | ||
| 15743 | Valternate_cursor_type = Qt; | ||
| 15744 | |||
| 15745 | DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist, | ||
| 15746 | doc: /* Alist specifying how to blink the cursor off. | ||
| 15747 | Each element has the form (ON-STATE . OFF-STATE). Whenever the | ||
| 15748 | `cursor-type' frame-parameter or variable equals ON-STATE, | ||
| 15749 | comparing using `equal', Emacs uses OFF-STATE to specify | ||
| 15750 | how to blink it off. */); | ||
| 15751 | Vblink_cursor_alist = Qnil; | ||
| 15523 | 15752 | ||
| 15524 | DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p, | 15753 | DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p, |
| 15525 | doc: /* *Non-nil means scroll the display automatically to make point visible. */); | 15754 | doc: /* *Non-nil means scroll the display automatically to make point visible. */); |