diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 112 | ||||
| -rw-r--r-- | src/biditype.h | 5 | ||||
| -rw-r--r-- | src/cmds.c | 105 | ||||
| -rw-r--r-- | src/composite.c | 3 | ||||
| -rw-r--r-- | src/dispextern.h | 10 | ||||
| -rw-r--r-- | src/image.c | 401 | ||||
| -rw-r--r-- | src/keyboard.c | 14 | ||||
| -rw-r--r-- | src/marker.c | 4 | ||||
| -rw-r--r-- | src/nsimage.m | 12 | ||||
| -rw-r--r-- | src/nsterm.m | 12 | ||||
| -rw-r--r-- | src/term.c | 45 | ||||
| -rw-r--r-- | src/w32uniscribe.c | 48 | ||||
| -rw-r--r-- | src/xdisp.c | 319 | ||||
| -rw-r--r-- | src/xselect.c | 243 | ||||
| -rw-r--r-- | src/xterm.c | 2 | ||||
| -rw-r--r-- | src/xterm.h | 2 |
16 files changed, 546 insertions, 791 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 8a3714bcf0d..4b4f82aa4c8 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,115 @@ | |||
| 1 | 2010-09-05 Juanma Barranquero <lekktu@gmail.com> | ||
| 2 | |||
| 3 | * biditype.h: Regenerate. | ||
| 4 | |||
| 5 | 2010-09-04 Andreas Schwab <schwab@linux-m68k.org> | ||
| 6 | |||
| 7 | * nsimage.m (ns_load_image): Check argument types. | ||
| 8 | |||
| 9 | * image.c: Remove all uses of gcpro. | ||
| 10 | (xpm_load): Check all lisp types. | ||
| 11 | (pbm_load): Likewise. | ||
| 12 | (png_load): Likewise. | ||
| 13 | (jpeg_load): Likewise. | ||
| 14 | (tiff_load): Likewise. | ||
| 15 | (gif_load): Likewise. | ||
| 16 | (imagemagick_load_image): Likewise. | ||
| 17 | (imagemagick_load): Likewise. | ||
| 18 | (svg_load): Likewise. | ||
| 19 | (gs_load): Likewise. | ||
| 20 | |||
| 21 | 2010-09-04 Eli Zaretskii <eliz@gnu.org> | ||
| 22 | |||
| 23 | * w32uniscribe.c (uniscribe_shape): Update commentary. Don't | ||
| 24 | try to reorder grapheme clusters, since LGSTRING should always | ||
| 25 | hold them in the logical order. | ||
| 26 | (uniscribe_encode_char, uniscribe_shape): Force ScriptShape to | ||
| 27 | return glyph codes in the logical order. | ||
| 28 | |||
| 29 | 2010-09-04 Andreas Schwab <schwab@linux-m68k.org> | ||
| 30 | |||
| 31 | * image.c (imagemagick_image_p): Replace bcopy by memcpy. | ||
| 32 | (imagemagick_load_image): Fix type mismatch. | ||
| 33 | (Fimagemagick_types): Likewise. Doc fix. | ||
| 34 | |||
| 35 | 2010-09-02 Jan Djärv <jan.h.d@swipnet.se> | ||
| 36 | |||
| 37 | * xterm.h (struct dpyinfo): Remove cut_buffers_initialized. | ||
| 38 | |||
| 39 | * xterm.c (x_term_init): Don't set dpyinfo->cut_buffers_initialized. | ||
| 40 | |||
| 41 | * xselect.c: Remove declaration of cut-buffer objects and functions. | ||
| 42 | (symbol_to_x_atom): Remove mapping to XA_CUT_BUFFERn. | ||
| 43 | (x_atom_to_symbol): Remove mapping to QCUT_BUFFERn. | ||
| 44 | (Fx_get_cut_buffer_internal, Fx_store_cut_buffer_internal) | ||
| 45 | (Fx_rotate_cut_buffers_internal): Remove. | ||
| 46 | (syms_of_xselect): Remove defsubr of above. | ||
| 47 | Remove intern of QCUT_BUFFERn. | ||
| 48 | |||
| 49 | 2010-09-01 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 50 | |||
| 51 | * cmds.c (Vblink_paren_function): Remove. | ||
| 52 | (internal_self_insert): Make it insert N chars at a time. | ||
| 53 | Don't call blink-paren-function. | ||
| 54 | (Fself_insert_command): Adjust accordingly. | ||
| 55 | (syms_of_cmds): Don't declare blink-paren-function. | ||
| 56 | |||
| 57 | 2010-08-31 Kenichi Handa <handa@m17n.org> | ||
| 58 | |||
| 59 | * dispextern.h (FACE_FOR_CHAR): Use an ASCII face for 8-bit | ||
| 60 | characters. | ||
| 61 | |||
| 62 | * term.c (encode_terminal_code): Fix the previous change. | ||
| 63 | (produce_glyphs): Don't set it->char_to_display here. Don't | ||
| 64 | handle unibyte-display-via-language-environment here. | ||
| 65 | (produce_special_glyphs): Set temp_it.char_to_display before | ||
| 66 | calling produce_glyphs. | ||
| 67 | |||
| 68 | * xdisp.c (get_next_display_element): Set it->char_to_display | ||
| 69 | here. Convert all 8-bit bytes from unibyte buffer/string to 8-bit | ||
| 70 | characters. | ||
| 71 | (get_overlay_arrow_glyph_row): Set it.char_to_display too before | ||
| 72 | calling PRODUCE_GLYPHS. | ||
| 73 | (append_space_for_newline): Save and store it->char_to_display. | ||
| 74 | Set it->char_to_display before calling PRODUCE_GLYPHS. | ||
| 75 | (extend_face_to_end_of_line): Set it->char_to_display before | ||
| 76 | calling PRODUCE_GLYPHS. | ||
| 77 | (get_glyph_face_and_encoding): Set the glyph code an 8-bit | ||
| 78 | character to its byte value. | ||
| 79 | (get_char_glyph_code): New function. | ||
| 80 | (produce_stretch_glyph): Set it2.char_to_display too before | ||
| 81 | calling x_produce_glyphs. | ||
| 82 | (x_produce_glyphs): Simplify by using the same code for ASCII and | ||
| 83 | non-ASCII characters. Don't set it->char_to_display here. Don't | ||
| 84 | handle unibyte-display-via-language-environment here. For a | ||
| 85 | charater of no glyph, use font->space_width instead of FONT_WIDTH. | ||
| 86 | |||
| 87 | 2010-08-31 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 88 | |||
| 89 | * keyboard.c (Fwindow_system): Fix compilation for USE_LISP_UNION_TYPE. | ||
| 90 | |||
| 91 | 2010-08-31 Chong Yidong <cyd@stupidchicken.com> | ||
| 92 | |||
| 93 | * keyboard.c (command_loop_1): Don't call x-set-selection on tty. | ||
| 94 | |||
| 95 | 2010-08-30 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 96 | |||
| 97 | * marker.c (Fcopy_marker): Make the first arg optional. | ||
| 98 | |||
| 99 | 2010-08-30 Kenichi Handa <handa@m17n.org> | ||
| 100 | |||
| 101 | * composite.c (composition_update_it): Fix computing of | ||
| 102 | cmp_it->width. | ||
| 103 | |||
| 104 | 2010-08-29 Kenichi Handa <handa@m17n.org> | ||
| 105 | |||
| 106 | * term.c (encode_terminal_code): Encode byte chars to the | ||
| 107 | correspnding bytes. | ||
| 108 | |||
| 109 | 2010-08-29 Jan Djärv <jan.h.d@swipnet.se> | ||
| 110 | |||
| 111 | * nsterm.m (ns_draw_window_cursor): Draw BAR_CURSOR correct for R2L. | ||
| 112 | |||
| 1 | 2010-08-26 Kenichi Handa <handa@m17n.org> | 113 | 2010-08-26 Kenichi Handa <handa@m17n.org> |
| 2 | 114 | ||
| 3 | * xdisp.c (compute_stop_pos): Pay attention to bidi scan direction | 115 | * xdisp.c (compute_stop_pos): Pay attention to bidi scan direction |
diff --git a/src/biditype.h b/src/biditype.h index 60fc6374f39..868aabd9ea6 100644 --- a/src/biditype.h +++ b/src/biditype.h | |||
| @@ -83,7 +83,8 @@ | |||
| 83 | { 0x0671, 0x06D5, STRONG_AL }, | 83 | { 0x0671, 0x06D5, STRONG_AL }, |
| 84 | { 0x06D6, 0x06DC, WEAK_NSM }, | 84 | { 0x06D6, 0x06DC, WEAK_NSM }, |
| 85 | { 0x06DD, 0x06DD, WEAK_AN }, | 85 | { 0x06DD, 0x06DD, WEAK_AN }, |
| 86 | { 0x06DE, 0x06E4, WEAK_NSM }, | 86 | { 0x06DE, 0x06DE, NEUTRAL_ON }, |
| 87 | { 0x06DF, 0x06E4, WEAK_NSM }, | ||
| 87 | { 0x06E5, 0x06E6, STRONG_AL }, | 88 | { 0x06E5, 0x06E6, STRONG_AL }, |
| 88 | { 0x06E7, 0x06E8, WEAK_NSM }, | 89 | { 0x06E7, 0x06E8, WEAK_NSM }, |
| 89 | { 0x06E9, 0x06E9, NEUTRAL_ON }, | 90 | { 0x06E9, 0x06E9, NEUTRAL_ON }, |
| @@ -271,7 +272,7 @@ | |||
| 271 | { 0x2080, 0x2089, WEAK_EN }, | 272 | { 0x2080, 0x2089, WEAK_EN }, |
| 272 | { 0x208A, 0x208B, WEAK_ES }, | 273 | { 0x208A, 0x208B, WEAK_ES }, |
| 273 | { 0x208C, 0x208E, NEUTRAL_ON }, | 274 | { 0x208C, 0x208E, NEUTRAL_ON }, |
| 274 | { 0x20A0, 0x20B8, WEAK_ET }, | 275 | { 0x20A0, 0x20B9, WEAK_ET }, |
| 275 | { 0x20D0, 0x20F0, WEAK_NSM }, | 276 | { 0x20D0, 0x20F0, WEAK_NSM }, |
| 276 | { 0x2100, 0x2101, NEUTRAL_ON }, | 277 | { 0x2100, 0x2101, NEUTRAL_ON }, |
| 277 | { 0x2103, 0x2106, NEUTRAL_ON }, | 278 | { 0x2103, 0x2106, NEUTRAL_ON }, |
diff --git a/src/cmds.c b/src/cmds.c index f306ede7ca5..f12e759b7a6 100644 --- a/src/cmds.c +++ b/src/cmds.c | |||
| @@ -32,7 +32,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 32 | #include "dispextern.h" | 32 | #include "dispextern.h" |
| 33 | #include "frame.h" | 33 | #include "frame.h" |
| 34 | 34 | ||
| 35 | Lisp_Object Qkill_forward_chars, Qkill_backward_chars, Vblink_paren_function; | 35 | Lisp_Object Qkill_forward_chars, Qkill_backward_chars; |
| 36 | 36 | ||
| 37 | /* A possible value for a buffer's overwrite-mode variable. */ | 37 | /* A possible value for a buffer's overwrite-mode variable. */ |
| 38 | Lisp_Object Qoverwrite_mode_binary; | 38 | Lisp_Object Qoverwrite_mode_binary; |
| @@ -304,36 +304,16 @@ After insertion, the value of `auto-fill-function' is called if the | |||
| 304 | { | 304 | { |
| 305 | int character = translate_char (Vtranslation_table_for_input, | 305 | int character = translate_char (Vtranslation_table_for_input, |
| 306 | XINT (last_command_event)); | 306 | XINT (last_command_event)); |
| 307 | if (XINT (n) >= 2 && NILP (current_buffer->overwrite_mode)) | 307 | int val = internal_self_insert (character, XFASTINT (n)); |
| 308 | { | 308 | if (val == 2) |
| 309 | XSETFASTINT (n, XFASTINT (n) - 2); | 309 | nonundocount = 0; |
| 310 | /* The first one might want to expand an abbrev. */ | 310 | frame_make_pointer_invisible (); |
| 311 | internal_self_insert (character, 1); | ||
| 312 | /* The bulk of the copies of this char can be inserted simply. | ||
| 313 | We don't have to handle a user-specified face specially | ||
| 314 | because it will get inherited from the first char inserted. */ | ||
| 315 | Finsert_char (make_number (character), n, Qt); | ||
| 316 | /* The last one might want to auto-fill. */ | ||
| 317 | internal_self_insert (character, 0); | ||
| 318 | } | ||
| 319 | else | ||
| 320 | while (XINT (n) > 0) | ||
| 321 | { | ||
| 322 | int val; | ||
| 323 | /* Ok since old and new vals both nonneg */ | ||
| 324 | XSETFASTINT (n, XFASTINT (n) - 1); | ||
| 325 | val = internal_self_insert (character, XFASTINT (n) != 0); | ||
| 326 | if (val == 2) | ||
| 327 | nonundocount = 0; | ||
| 328 | frame_make_pointer_invisible (); | ||
| 329 | } | ||
| 330 | } | 311 | } |
| 331 | 312 | ||
| 332 | return Qnil; | 313 | return Qnil; |
| 333 | } | 314 | } |
| 334 | 315 | ||
| 335 | /* Insert character C. If NOAUTOFILL is nonzero, don't do autofill | 316 | /* Insert N times character C |
| 336 | even if it is enabled. | ||
| 337 | 317 | ||
| 338 | If this insertion is suitable for direct output (completely simple), | 318 | If this insertion is suitable for direct output (completely simple), |
| 339 | return 0. A value of 1 indicates this *might* not have been simple. | 319 | return 0. A value of 1 indicates this *might* not have been simple. |
| @@ -343,12 +323,12 @@ static Lisp_Object Qexpand_abbrev; | |||
| 343 | static Lisp_Object Qpost_self_insert_hook, Vpost_self_insert_hook; | 323 | static Lisp_Object Qpost_self_insert_hook, Vpost_self_insert_hook; |
| 344 | 324 | ||
| 345 | static int | 325 | static int |
| 346 | internal_self_insert (int c, int noautofill) | 326 | internal_self_insert (int c, int n) |
| 347 | { | 327 | { |
| 348 | int hairy = 0; | 328 | int hairy = 0; |
| 349 | Lisp_Object tem; | 329 | Lisp_Object tem; |
| 350 | register enum syntaxcode synt; | 330 | register enum syntaxcode synt; |
| 351 | Lisp_Object overwrite, string; | 331 | Lisp_Object overwrite; |
| 352 | /* Length of multi-byte form of C. */ | 332 | /* Length of multi-byte form of C. */ |
| 353 | int len; | 333 | int len; |
| 354 | /* Working buffer and pointer for multi-byte form of C. */ | 334 | /* Working buffer and pointer for multi-byte form of C. */ |
| @@ -391,32 +371,22 @@ internal_self_insert (int c, int noautofill) | |||
| 391 | /* This is the character after point. */ | 371 | /* This is the character after point. */ |
| 392 | int c2 = FETCH_CHAR (PT_BYTE); | 372 | int c2 = FETCH_CHAR (PT_BYTE); |
| 393 | 373 | ||
| 394 | /* Column the cursor should be placed at after this insertion. | ||
| 395 | The correct value should be calculated only when necessary. */ | ||
| 396 | int target_clm = 0; | ||
| 397 | |||
| 398 | /* Overwriting in binary-mode always replaces C2 by C. | 374 | /* Overwriting in binary-mode always replaces C2 by C. |
| 399 | Overwriting in textual-mode doesn't always do that. | 375 | Overwriting in textual-mode doesn't always do that. |
| 400 | It inserts newlines in the usual way, | 376 | It inserts newlines in the usual way, |
| 401 | and inserts any character at end of line | 377 | and inserts any character at end of line |
| 402 | or before a tab if it doesn't use the whole width of the tab. */ | 378 | or before a tab if it doesn't use the whole width of the tab. */ |
| 403 | if (EQ (overwrite, Qoverwrite_mode_binary) | 379 | if (EQ (overwrite, Qoverwrite_mode_binary)) |
| 404 | || (c != '\n' | 380 | chars_to_delete = n; |
| 405 | && c2 != '\n' | 381 | else if (c != '\n' && c2 != '\n') |
| 406 | && ! (c2 == '\t' | ||
| 407 | && XINT (current_buffer->tab_width) > 0 | ||
| 408 | && XFASTINT (current_buffer->tab_width) < 20 | ||
| 409 | && (target_clm = ((int) current_column () /* iftc */ | ||
| 410 | + XINT (Fchar_width (make_number (c)))), | ||
| 411 | target_clm % XFASTINT (current_buffer->tab_width))))) | ||
| 412 | { | 382 | { |
| 413 | int pos = PT; | 383 | int pos = PT; |
| 414 | int pos_byte = PT_BYTE; | 384 | int pos_byte = PT_BYTE; |
| 385 | /* Column the cursor should be placed at after this insertion. | ||
| 386 | The correct value should be calculated only when necessary. */ | ||
| 387 | int target_clm = ((int) current_column () /* iftc */ | ||
| 388 | + n * XINT (Fchar_width (make_number (c)))); | ||
| 415 | 389 | ||
| 416 | if (target_clm == 0) | ||
| 417 | chars_to_delete = 1; | ||
| 418 | else | ||
| 419 | { | ||
| 420 | /* The actual cursor position after the trial of moving | 390 | /* The actual cursor position after the trial of moving |
| 421 | to column TARGET_CLM. It is greater than TARGET_CLM | 391 | to column TARGET_CLM. It is greater than TARGET_CLM |
| 422 | if the TARGET_CLM is middle of multi-column | 392 | if the TARGET_CLM is middle of multi-column |
| @@ -428,14 +398,18 @@ internal_self_insert (int c, int noautofill) | |||
| 428 | chars_to_delete = PT - pos; | 398 | chars_to_delete = PT - pos; |
| 429 | 399 | ||
| 430 | if (actual_clm > target_clm) | 400 | if (actual_clm > target_clm) |
| 431 | { | 401 | { /* We will delete too many columns. Let's fill columns |
| 432 | /* We will delete too many columns. Let's fill columns | ||
| 433 | by spaces so that the remaining text won't move. */ | 402 | by spaces so that the remaining text won't move. */ |
| 403 | EMACS_INT actual = PT_BYTE; | ||
| 404 | DEC_POS (actual); | ||
| 405 | if (FETCH_CHAR (actual) == '\t') | ||
| 406 | /* Rather than add spaces, let's just keep the tab. */ | ||
| 407 | chars_to_delete--; | ||
| 408 | else | ||
| 434 | spaces_to_insert = actual_clm - target_clm; | 409 | spaces_to_insert = actual_clm - target_clm; |
| 435 | } | 410 | } |
| 436 | } | 411 | |
| 437 | SET_PT_BOTH (pos, pos_byte); | 412 | SET_PT_BOTH (pos, pos_byte); |
| 438 | hairy = 2; | ||
| 439 | } | 413 | } |
| 440 | hairy = 2; | 414 | hairy = 2; |
| 441 | } | 415 | } |
| @@ -474,16 +448,30 @@ internal_self_insert (int c, int noautofill) | |||
| 474 | 448 | ||
| 475 | if (chars_to_delete) | 449 | if (chars_to_delete) |
| 476 | { | 450 | { |
| 477 | string = make_string_from_bytes (str, 1, len); | 451 | int mc = ((NILP (current_buffer->enable_multibyte_characters) |
| 452 | && SINGLE_BYTE_CHAR_P (c)) | ||
| 453 | ? UNIBYTE_TO_CHAR (c) : c); | ||
| 454 | Lisp_Object string = Fmake_string (make_number (n), make_number (mc)); | ||
| 455 | |||
| 478 | if (spaces_to_insert) | 456 | if (spaces_to_insert) |
| 479 | { | 457 | { |
| 480 | tem = Fmake_string (make_number (spaces_to_insert), | 458 | tem = Fmake_string (make_number (spaces_to_insert), |
| 481 | make_number (' ')); | 459 | make_number (' ')); |
| 482 | string = concat2 (tem, string); | 460 | string = concat2 (string, tem); |
| 483 | } | 461 | } |
| 484 | 462 | ||
| 485 | replace_range (PT, PT + chars_to_delete, string, 1, 1, 1); | 463 | replace_range (PT, PT + chars_to_delete, string, 1, 1, 1); |
| 486 | Fforward_char (make_number (1 + spaces_to_insert)); | 464 | Fforward_char (make_number (n + spaces_to_insert)); |
| 465 | } | ||
| 466 | else if (n > 1) | ||
| 467 | { | ||
| 468 | USE_SAFE_ALLOCA; | ||
| 469 | unsigned char *strn, *p; | ||
| 470 | SAFE_ALLOCA (strn, unsigned char*, n * len); | ||
| 471 | for (p = strn; n > 0; n--, p += len) | ||
| 472 | memcpy (p, str, len); | ||
| 473 | insert_and_inherit (strn, p - strn); | ||
| 474 | SAFE_FREE (); | ||
| 487 | } | 475 | } |
| 488 | else | 476 | else |
| 489 | insert_and_inherit (str, len); | 477 | insert_and_inherit (str, len); |
| @@ -491,7 +479,6 @@ internal_self_insert (int c, int noautofill) | |||
| 491 | if ((CHAR_TABLE_P (Vauto_fill_chars) | 479 | if ((CHAR_TABLE_P (Vauto_fill_chars) |
| 492 | ? !NILP (CHAR_TABLE_REF (Vauto_fill_chars, c)) | 480 | ? !NILP (CHAR_TABLE_REF (Vauto_fill_chars, c)) |
| 493 | : (c == ' ' || c == '\n')) | 481 | : (c == ' ' || c == '\n')) |
| 494 | && !noautofill | ||
| 495 | && !NILP (current_buffer->auto_fill_function)) | 482 | && !NILP (current_buffer->auto_fill_function)) |
| 496 | { | 483 | { |
| 497 | Lisp_Object tem; | 484 | Lisp_Object tem; |
| @@ -509,13 +496,6 @@ internal_self_insert (int c, int noautofill) | |||
| 509 | hairy = 2; | 496 | hairy = 2; |
| 510 | } | 497 | } |
| 511 | 498 | ||
| 512 | if ((synt == Sclose || synt == Smath) | ||
| 513 | && !NILP (Vblink_paren_function) && INTERACTIVE | ||
| 514 | && !noautofill) | ||
| 515 | { | ||
| 516 | call0 (Vblink_paren_function); | ||
| 517 | hairy = 2; | ||
| 518 | } | ||
| 519 | /* Run hooks for electric keys. */ | 499 | /* Run hooks for electric keys. */ |
| 520 | call1 (Vrun_hooks, Qpost_self_insert_hook); | 500 | call1 (Vrun_hooks, Qpost_self_insert_hook); |
| 521 | 501 | ||
| @@ -547,11 +527,6 @@ syms_of_cmds (void) | |||
| 547 | This run is run after inserting the charater. */); | 527 | This run is run after inserting the charater. */); |
| 548 | Vpost_self_insert_hook = Qnil; | 528 | Vpost_self_insert_hook = Qnil; |
| 549 | 529 | ||
| 550 | DEFVAR_LISP ("blink-paren-function", &Vblink_paren_function, | ||
| 551 | doc: /* Function called, if non-nil, whenever a close parenthesis is inserted. | ||
| 552 | More precisely, a char with closeparen syntax is self-inserted. */); | ||
| 553 | Vblink_paren_function = Qnil; | ||
| 554 | |||
| 555 | defsubr (&Sforward_point); | 530 | defsubr (&Sforward_point); |
| 556 | defsubr (&Sforward_char); | 531 | defsubr (&Sforward_char); |
| 557 | defsubr (&Sbackward_char); | 532 | defsubr (&Sbackward_char); |
diff --git a/src/composite.c b/src/composite.c index 233f9ac8969..bc5a67ef6e2 100644 --- a/src/composite.c +++ b/src/composite.c | |||
| @@ -1440,8 +1440,7 @@ composition_update_it (struct composition_it *cmp_it, EMACS_INT charpos, EMACS_I | |||
| 1440 | { | 1440 | { |
| 1441 | c = XINT (LGSTRING_CHAR (gstring, i)); | 1441 | c = XINT (LGSTRING_CHAR (gstring, i)); |
| 1442 | cmp_it->nbytes += CHAR_BYTES (c); | 1442 | cmp_it->nbytes += CHAR_BYTES (c); |
| 1443 | cmp_it->width = (LGLYPH_WIDTH (glyph) > 0 | 1443 | cmp_it->width += CHAR_WIDTH (c); |
| 1444 | ? CHAR_WIDTH (LGLYPH_CHAR (glyph)) : 0); | ||
| 1445 | } | 1444 | } |
| 1446 | } | 1445 | } |
| 1447 | return c; | 1446 | return c; |
diff --git a/src/dispextern.h b/src/dispextern.h index 9e9344f57f7..ecf03569bce 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -1724,7 +1724,7 @@ struct face_cache | |||
| 1724 | This macro is only meaningful for multibyte character CHAR. */ | 1724 | This macro is only meaningful for multibyte character CHAR. */ |
| 1725 | 1725 | ||
| 1726 | #define FACE_FOR_CHAR(F, FACE, CHAR, POS, OBJECT) \ | 1726 | #define FACE_FOR_CHAR(F, FACE, CHAR, POS, OBJECT) \ |
| 1727 | (ASCII_CHAR_P (CHAR) \ | 1727 | ((ASCII_CHAR_P (CHAR) || CHAR_BYTE8_P (CHAR)) \ |
| 1728 | ? (FACE)->ascii_face->id \ | 1728 | ? (FACE)->ascii_face->id \ |
| 1729 | : face_for_char ((F), (FACE), (CHAR), (POS), (OBJECT))) | 1729 | : face_for_char ((F), (FACE), (CHAR), (POS), (OBJECT))) |
| 1730 | 1730 | ||
| @@ -2290,9 +2290,11 @@ struct it | |||
| 2290 | composition. */ | 2290 | composition. */ |
| 2291 | struct composition_it cmp_it; | 2291 | struct composition_it cmp_it; |
| 2292 | 2292 | ||
| 2293 | /* The character to display, possibly translated to multibyte | 2293 | /* The character to display, possibly translated to multibyte if |
| 2294 | if unibyte_display_via_language_environment is set. This | 2294 | multibyte_p is zero or unibyte_display_via_language_environment |
| 2295 | is set after produce_glyphs has been called. */ | 2295 | is set. This is set after get_next_display_element has been |
| 2296 | called. If we are setting it->C directly before calling | ||
| 2297 | PRODUCE_GLYPHS, this should be set beforehand too. */ | ||
| 2296 | int char_to_display; | 2298 | int char_to_display; |
| 2297 | 2299 | ||
| 2298 | /* If what == IT_IMAGE, the id of the image to display. */ | 2300 | /* If what == IT_IMAGE, the id of the image to display. */ |
diff --git a/src/image.c b/src/image.c index ae4bf2fd937..ff0bbc1d688 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -1735,7 +1735,6 @@ lookup_image (struct frame *f, Lisp_Object spec) | |||
| 1735 | struct image_cache *c; | 1735 | struct image_cache *c; |
| 1736 | struct image *img; | 1736 | struct image *img; |
| 1737 | unsigned hash; | 1737 | unsigned hash; |
| 1738 | struct gcpro gcpro1; | ||
| 1739 | EMACS_TIME now; | 1738 | EMACS_TIME now; |
| 1740 | 1739 | ||
| 1741 | /* F must be a window-system frame, and SPEC must be a valid image | 1740 | /* F must be a window-system frame, and SPEC must be a valid image |
| @@ -1745,8 +1744,6 @@ lookup_image (struct frame *f, Lisp_Object spec) | |||
| 1745 | 1744 | ||
| 1746 | c = FRAME_IMAGE_CACHE (f); | 1745 | c = FRAME_IMAGE_CACHE (f); |
| 1747 | 1746 | ||
| 1748 | GCPRO1 (spec); | ||
| 1749 | |||
| 1750 | /* Look up SPEC in the hash table of the image cache. */ | 1747 | /* Look up SPEC in the hash table of the image cache. */ |
| 1751 | hash = sxhash (spec, 0); | 1748 | hash = sxhash (spec, 0); |
| 1752 | img = search_image_cache (f, spec, hash); | 1749 | img = search_image_cache (f, spec, hash); |
| @@ -1838,8 +1835,6 @@ lookup_image (struct frame *f, Lisp_Object spec) | |||
| 1838 | EMACS_GET_TIME (now); | 1835 | EMACS_GET_TIME (now); |
| 1839 | img->timestamp = EMACS_SECS (now); | 1836 | img->timestamp = EMACS_SECS (now); |
| 1840 | 1837 | ||
| 1841 | UNGCPRO; | ||
| 1842 | |||
| 1843 | /* Value is the image id. */ | 1838 | /* Value is the image id. */ |
| 1844 | return img->id; | 1839 | return img->id; |
| 1845 | } | 1840 | } |
| @@ -2179,16 +2174,13 @@ Lisp_Object | |||
| 2179 | x_find_image_file (Lisp_Object file) | 2174 | x_find_image_file (Lisp_Object file) |
| 2180 | { | 2175 | { |
| 2181 | Lisp_Object file_found, search_path; | 2176 | Lisp_Object file_found, search_path; |
| 2182 | struct gcpro gcpro1, gcpro2; | ||
| 2183 | int fd; | 2177 | int fd; |
| 2184 | 2178 | ||
| 2185 | file_found = Qnil; | ||
| 2186 | /* TODO I think this should use something like image-load-path | 2179 | /* TODO I think this should use something like image-load-path |
| 2187 | instead. Unfortunately, that can contain non-string elements. */ | 2180 | instead. Unfortunately, that can contain non-string elements. */ |
| 2188 | search_path = Fcons (Fexpand_file_name (build_string ("images"), | 2181 | search_path = Fcons (Fexpand_file_name (build_string ("images"), |
| 2189 | Vdata_directory), | 2182 | Vdata_directory), |
| 2190 | Vx_bitmap_file_path); | 2183 | Vx_bitmap_file_path); |
| 2191 | GCPRO2 (file_found, search_path); | ||
| 2192 | 2184 | ||
| 2193 | /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */ | 2185 | /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */ |
| 2194 | fd = openp (search_path, file, Qnil, &file_found, Qnil); | 2186 | fd = openp (search_path, file, Qnil, &file_found, Qnil); |
| @@ -2201,7 +2193,6 @@ x_find_image_file (Lisp_Object file) | |||
| 2201 | close (fd); | 2193 | close (fd); |
| 2202 | } | 2194 | } |
| 2203 | 2195 | ||
| 2204 | UNGCPRO; | ||
| 2205 | return file_found; | 2196 | return file_found; |
| 2206 | } | 2197 | } |
| 2207 | 2198 | ||
| @@ -2875,14 +2866,11 @@ xbm_load (struct frame *f, struct image *img) | |||
| 2875 | Lisp_Object file; | 2866 | Lisp_Object file; |
| 2876 | unsigned char *contents; | 2867 | unsigned char *contents; |
| 2877 | int size; | 2868 | int size; |
| 2878 | struct gcpro gcpro1; | ||
| 2879 | 2869 | ||
| 2880 | file = x_find_image_file (file_name); | 2870 | file = x_find_image_file (file_name); |
| 2881 | GCPRO1 (file); | ||
| 2882 | if (!STRINGP (file)) | 2871 | if (!STRINGP (file)) |
| 2883 | { | 2872 | { |
| 2884 | image_error ("Cannot find image file `%s'", file_name, Qnil); | 2873 | image_error ("Cannot find image file `%s'", file_name, Qnil); |
| 2885 | UNGCPRO; | ||
| 2886 | return 0; | 2874 | return 0; |
| 2887 | } | 2875 | } |
| 2888 | 2876 | ||
| @@ -2890,12 +2878,10 @@ xbm_load (struct frame *f, struct image *img) | |||
| 2890 | if (contents == NULL) | 2878 | if (contents == NULL) |
| 2891 | { | 2879 | { |
| 2892 | image_error ("Error loading XBM image `%s'", img->spec, Qnil); | 2880 | image_error ("Error loading XBM image `%s'", img->spec, Qnil); |
| 2893 | UNGCPRO; | ||
| 2894 | return 0; | 2881 | return 0; |
| 2895 | } | 2882 | } |
| 2896 | 2883 | ||
| 2897 | success_p = xbm_load_image (f, img, contents, contents + size); | 2884 | success_p = xbm_load_image (f, img, contents, contents + size); |
| 2898 | UNGCPRO; | ||
| 2899 | } | 2885 | } |
| 2900 | else | 2886 | else |
| 2901 | { | 2887 | { |
| @@ -3456,12 +3442,31 @@ xpm_load (struct frame *f, struct image *img) | |||
| 3456 | CONSP (tail); | 3442 | CONSP (tail); |
| 3457 | ++i, tail = XCDR (tail)) | 3443 | ++i, tail = XCDR (tail)) |
| 3458 | { | 3444 | { |
| 3459 | Lisp_Object name = XCAR (XCAR (tail)); | 3445 | Lisp_Object name; |
| 3460 | Lisp_Object color = XCDR (XCAR (tail)); | 3446 | Lisp_Object color; |
| 3461 | xpm_syms[i].name = (char *) alloca (SCHARS (name) + 1); | 3447 | |
| 3462 | strcpy (xpm_syms[i].name, SDATA (name)); | 3448 | if (!CONSP (XCAR (tail))) |
| 3463 | xpm_syms[i].value = (char *) alloca (SCHARS (color) + 1); | 3449 | { |
| 3464 | strcpy (xpm_syms[i].value, SDATA (color)); | 3450 | xpm_syms[i].name = ""; |
| 3451 | xpm_syms[i].value = ""; | ||
| 3452 | continue; | ||
| 3453 | } | ||
| 3454 | name = XCAR (XCAR (tail)); | ||
| 3455 | color = XCDR (XCAR (tail)); | ||
| 3456 | if (STRINGP (name)) | ||
| 3457 | { | ||
| 3458 | xpm_syms[i].name = (char *) alloca (SCHARS (name) + 1); | ||
| 3459 | strcpy (xpm_syms[i].name, SDATA (name)); | ||
| 3460 | } | ||
| 3461 | else | ||
| 3462 | xpm_syms[i].name = ""; | ||
| 3463 | if (STRINGP (color)) | ||
| 3464 | { | ||
| 3465 | xpm_syms[i].value = (char *) alloca (SCHARS (color) + 1); | ||
| 3466 | strcpy (xpm_syms[i].value, SDATA (color)); | ||
| 3467 | } | ||
| 3468 | else | ||
| 3469 | xpm_syms[i].value = ""; | ||
| 3465 | } | 3470 | } |
| 3466 | } | 3471 | } |
| 3467 | 3472 | ||
| @@ -3487,6 +3492,9 @@ xpm_load (struct frame *f, struct image *img) | |||
| 3487 | if (!STRINGP (file)) | 3492 | if (!STRINGP (file)) |
| 3488 | { | 3493 | { |
| 3489 | image_error ("Cannot find image file `%s'", specified_file, Qnil); | 3494 | image_error ("Cannot find image file `%s'", specified_file, Qnil); |
| 3495 | #ifdef ALLOC_XPM_COLORS | ||
| 3496 | xpm_free_color_cache (); | ||
| 3497 | #endif | ||
| 3490 | return 0; | 3498 | return 0; |
| 3491 | } | 3499 | } |
| 3492 | 3500 | ||
| @@ -3505,6 +3513,14 @@ xpm_load (struct frame *f, struct image *img) | |||
| 3505 | else | 3513 | else |
| 3506 | { | 3514 | { |
| 3507 | Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL); | 3515 | Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL); |
| 3516 | if (!STRINGP (buffer)) | ||
| 3517 | { | ||
| 3518 | image_error ("Invalid image data `%s'", buffer, Qnil); | ||
| 3519 | #ifdef ALLOC_XPM_COLORS | ||
| 3520 | xpm_free_color_cache (); | ||
| 3521 | #endif | ||
| 3522 | return 0; | ||
| 3523 | } | ||
| 3508 | #ifdef HAVE_NTGUI | 3524 | #ifdef HAVE_NTGUI |
| 3509 | /* XpmCreatePixmapFromBuffer is not available in the Windows port | 3525 | /* XpmCreatePixmapFromBuffer is not available in the Windows port |
| 3510 | of libxpm. But XpmCreateImageFromBuffer almost does what we want. */ | 3526 | of libxpm. But XpmCreateImageFromBuffer almost does what we want. */ |
| @@ -4071,14 +4087,11 @@ xpm_load (struct frame *f, | |||
| 4071 | Lisp_Object file; | 4087 | Lisp_Object file; |
| 4072 | unsigned char *contents; | 4088 | unsigned char *contents; |
| 4073 | int size; | 4089 | int size; |
| 4074 | struct gcpro gcpro1; | ||
| 4075 | 4090 | ||
| 4076 | file = x_find_image_file (file_name); | 4091 | file = x_find_image_file (file_name); |
| 4077 | GCPRO1 (file); | ||
| 4078 | if (!STRINGP (file)) | 4092 | if (!STRINGP (file)) |
| 4079 | { | 4093 | { |
| 4080 | image_error ("Cannot find image file `%s'", file_name, Qnil); | 4094 | image_error ("Cannot find image file `%s'", file_name, Qnil); |
| 4081 | UNGCPRO; | ||
| 4082 | return 0; | 4095 | return 0; |
| 4083 | } | 4096 | } |
| 4084 | 4097 | ||
| @@ -4086,19 +4099,22 @@ xpm_load (struct frame *f, | |||
| 4086 | if (contents == NULL) | 4099 | if (contents == NULL) |
| 4087 | { | 4100 | { |
| 4088 | image_error ("Error loading XPM image `%s'", img->spec, Qnil); | 4101 | image_error ("Error loading XPM image `%s'", img->spec, Qnil); |
| 4089 | UNGCPRO; | ||
| 4090 | return 0; | 4102 | return 0; |
| 4091 | } | 4103 | } |
| 4092 | 4104 | ||
| 4093 | success_p = xpm_load_image (f, img, contents, contents + size); | 4105 | success_p = xpm_load_image (f, img, contents, contents + size); |
| 4094 | xfree (contents); | 4106 | xfree (contents); |
| 4095 | UNGCPRO; | ||
| 4096 | } | 4107 | } |
| 4097 | else | 4108 | else |
| 4098 | { | 4109 | { |
| 4099 | Lisp_Object data; | 4110 | Lisp_Object data; |
| 4100 | 4111 | ||
| 4101 | data = image_spec_value (img->spec, QCdata, NULL); | 4112 | data = image_spec_value (img->spec, QCdata, NULL); |
| 4113 | if (!STRINGP (data)) | ||
| 4114 | { | ||
| 4115 | image_error ("Invalid image data `%s'", data, Qnil); | ||
| 4116 | return 0; | ||
| 4117 | } | ||
| 4102 | success_p = xpm_load_image (f, img, SDATA (data), | 4118 | success_p = xpm_load_image (f, img, SDATA (data), |
| 4103 | SDATA (data) + SBYTES (data)); | 4119 | SDATA (data) + SBYTES (data)); |
| 4104 | } | 4120 | } |
| @@ -5090,14 +5106,11 @@ pbm_load (struct frame *f, struct image *img) | |||
| 5090 | XImagePtr ximg; | 5106 | XImagePtr ximg; |
| 5091 | Lisp_Object file, specified_file; | 5107 | Lisp_Object file, specified_file; |
| 5092 | enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type; | 5108 | enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type; |
| 5093 | struct gcpro gcpro1; | ||
| 5094 | unsigned char *contents = NULL; | 5109 | unsigned char *contents = NULL; |
| 5095 | unsigned char *end, *p; | 5110 | unsigned char *end, *p; |
| 5096 | int size; | 5111 | int size; |
| 5097 | 5112 | ||
| 5098 | specified_file = image_spec_value (img->spec, QCfile, NULL); | 5113 | specified_file = image_spec_value (img->spec, QCfile, NULL); |
| 5099 | file = Qnil; | ||
| 5100 | GCPRO1 (file); | ||
| 5101 | 5114 | ||
| 5102 | if (STRINGP (specified_file)) | 5115 | if (STRINGP (specified_file)) |
| 5103 | { | 5116 | { |
| @@ -5105,7 +5118,6 @@ pbm_load (struct frame *f, struct image *img) | |||
| 5105 | if (!STRINGP (file)) | 5118 | if (!STRINGP (file)) |
| 5106 | { | 5119 | { |
| 5107 | image_error ("Cannot find image file `%s'", specified_file, Qnil); | 5120 | image_error ("Cannot find image file `%s'", specified_file, Qnil); |
| 5108 | UNGCPRO; | ||
| 5109 | return 0; | 5121 | return 0; |
| 5110 | } | 5122 | } |
| 5111 | 5123 | ||
| @@ -5113,7 +5125,6 @@ pbm_load (struct frame *f, struct image *img) | |||
| 5113 | if (contents == NULL) | 5125 | if (contents == NULL) |
| 5114 | { | 5126 | { |
| 5115 | image_error ("Error reading `%s'", file, Qnil); | 5127 | image_error ("Error reading `%s'", file, Qnil); |
| 5116 | UNGCPRO; | ||
| 5117 | return 0; | 5128 | return 0; |
| 5118 | } | 5129 | } |
| 5119 | 5130 | ||
| @@ -5124,6 +5135,11 @@ pbm_load (struct frame *f, struct image *img) | |||
| 5124 | { | 5135 | { |
| 5125 | Lisp_Object data; | 5136 | Lisp_Object data; |
| 5126 | data = image_spec_value (img->spec, QCdata, NULL); | 5137 | data = image_spec_value (img->spec, QCdata, NULL); |
| 5138 | if (!STRINGP (data)) | ||
| 5139 | { | ||
| 5140 | image_error ("Invalid image data `%s'", data, Qnil); | ||
| 5141 | return 0; | ||
| 5142 | } | ||
| 5127 | p = SDATA (data); | 5143 | p = SDATA (data); |
| 5128 | end = p + SBYTES (data); | 5144 | end = p + SBYTES (data); |
| 5129 | } | 5145 | } |
| @@ -5134,7 +5150,6 @@ pbm_load (struct frame *f, struct image *img) | |||
| 5134 | image_error ("Not a PBM image: `%s'", img->spec, Qnil); | 5150 | image_error ("Not a PBM image: `%s'", img->spec, Qnil); |
| 5135 | error: | 5151 | error: |
| 5136 | xfree (contents); | 5152 | xfree (contents); |
| 5137 | UNGCPRO; | ||
| 5138 | return 0; | 5153 | return 0; |
| 5139 | } | 5154 | } |
| 5140 | 5155 | ||
| @@ -5336,7 +5351,6 @@ pbm_load (struct frame *f, struct image *img) | |||
| 5336 | img->width = width; | 5351 | img->width = width; |
| 5337 | img->height = height; */ | 5352 | img->height = height; */ |
| 5338 | 5353 | ||
| 5339 | UNGCPRO; | ||
| 5340 | xfree (contents); | 5354 | xfree (contents); |
| 5341 | return 1; | 5355 | return 1; |
| 5342 | } | 5356 | } |
| @@ -5576,7 +5590,6 @@ png_load (struct frame *f, struct image *img) | |||
| 5576 | Lisp_Object specified_data; | 5590 | Lisp_Object specified_data; |
| 5577 | int x, y, i; | 5591 | int x, y, i; |
| 5578 | XImagePtr ximg, mask_img = NULL; | 5592 | XImagePtr ximg, mask_img = NULL; |
| 5579 | struct gcpro gcpro1; | ||
| 5580 | png_struct *png_ptr = NULL; | 5593 | png_struct *png_ptr = NULL; |
| 5581 | png_info *info_ptr = NULL, *end_info = NULL; | 5594 | png_info *info_ptr = NULL, *end_info = NULL; |
| 5582 | FILE *volatile fp = NULL; | 5595 | FILE *volatile fp = NULL; |
| @@ -5593,8 +5606,6 @@ png_load (struct frame *f, struct image *img) | |||
| 5593 | /* Find out what file to load. */ | 5606 | /* Find out what file to load. */ |
| 5594 | specified_file = image_spec_value (img->spec, QCfile, NULL); | 5607 | specified_file = image_spec_value (img->spec, QCfile, NULL); |
| 5595 | specified_data = image_spec_value (img->spec, QCdata, NULL); | 5608 | specified_data = image_spec_value (img->spec, QCdata, NULL); |
| 5596 | file = Qnil; | ||
| 5597 | GCPRO1 (file); | ||
| 5598 | 5609 | ||
| 5599 | if (NILP (specified_data)) | 5610 | if (NILP (specified_data)) |
| 5600 | { | 5611 | { |
| @@ -5602,7 +5613,6 @@ png_load (struct frame *f, struct image *img) | |||
| 5602 | if (!STRINGP (file)) | 5613 | if (!STRINGP (file)) |
| 5603 | { | 5614 | { |
| 5604 | image_error ("Cannot find image file `%s'", specified_file, Qnil); | 5615 | image_error ("Cannot find image file `%s'", specified_file, Qnil); |
| 5605 | UNGCPRO; | ||
| 5606 | return 0; | 5616 | return 0; |
| 5607 | } | 5617 | } |
| 5608 | 5618 | ||
| @@ -5611,7 +5621,6 @@ png_load (struct frame *f, struct image *img) | |||
| 5611 | if (!fp) | 5621 | if (!fp) |
| 5612 | { | 5622 | { |
| 5613 | image_error ("Cannot open image file `%s'", file, Qnil); | 5623 | image_error ("Cannot open image file `%s'", file, Qnil); |
| 5614 | UNGCPRO; | ||
| 5615 | return 0; | 5624 | return 0; |
| 5616 | } | 5625 | } |
| 5617 | 5626 | ||
| @@ -5620,13 +5629,18 @@ png_load (struct frame *f, struct image *img) | |||
| 5620 | || fn_png_sig_cmp (sig, 0, sizeof sig)) | 5629 | || fn_png_sig_cmp (sig, 0, sizeof sig)) |
| 5621 | { | 5630 | { |
| 5622 | image_error ("Not a PNG file: `%s'", file, Qnil); | 5631 | image_error ("Not a PNG file: `%s'", file, Qnil); |
| 5623 | UNGCPRO; | ||
| 5624 | fclose (fp); | 5632 | fclose (fp); |
| 5625 | return 0; | 5633 | return 0; |
| 5626 | } | 5634 | } |
| 5627 | } | 5635 | } |
| 5628 | else | 5636 | else |
| 5629 | { | 5637 | { |
| 5638 | if (!STRINGP (specified_data)) | ||
| 5639 | { | ||
| 5640 | image_error ("Invalid image data `%s'", specified_data, Qnil); | ||
| 5641 | return 0; | ||
| 5642 | } | ||
| 5643 | |||
| 5630 | /* Read from memory. */ | 5644 | /* Read from memory. */ |
| 5631 | tbr.bytes = SDATA (specified_data); | 5645 | tbr.bytes = SDATA (specified_data); |
| 5632 | tbr.len = SBYTES (specified_data); | 5646 | tbr.len = SBYTES (specified_data); |
| @@ -5637,7 +5651,6 @@ png_load (struct frame *f, struct image *img) | |||
| 5637 | || fn_png_sig_cmp (tbr.bytes, 0, sizeof sig)) | 5651 | || fn_png_sig_cmp (tbr.bytes, 0, sizeof sig)) |
| 5638 | { | 5652 | { |
| 5639 | image_error ("Not a PNG image: `%s'", img->spec, Qnil); | 5653 | image_error ("Not a PNG image: `%s'", img->spec, Qnil); |
| 5640 | UNGCPRO; | ||
| 5641 | return 0; | 5654 | return 0; |
| 5642 | } | 5655 | } |
| 5643 | 5656 | ||
| @@ -5653,7 +5666,6 @@ png_load (struct frame *f, struct image *img) | |||
| 5653 | if (!png_ptr) | 5666 | if (!png_ptr) |
| 5654 | { | 5667 | { |
| 5655 | if (fp) fclose (fp); | 5668 | if (fp) fclose (fp); |
| 5656 | UNGCPRO; | ||
| 5657 | return 0; | 5669 | return 0; |
| 5658 | } | 5670 | } |
| 5659 | 5671 | ||
| @@ -5663,7 +5675,6 @@ png_load (struct frame *f, struct image *img) | |||
| 5663 | { | 5675 | { |
| 5664 | fn_png_destroy_read_struct (&png_ptr, NULL, NULL); | 5676 | fn_png_destroy_read_struct (&png_ptr, NULL, NULL); |
| 5665 | if (fp) fclose (fp); | 5677 | if (fp) fclose (fp); |
| 5666 | UNGCPRO; | ||
| 5667 | return 0; | 5678 | return 0; |
| 5668 | } | 5679 | } |
| 5669 | 5680 | ||
| @@ -5673,7 +5684,6 @@ png_load (struct frame *f, struct image *img) | |||
| 5673 | { | 5684 | { |
| 5674 | fn_png_destroy_read_struct (&png_ptr, &info_ptr, NULL); | 5685 | fn_png_destroy_read_struct (&png_ptr, &info_ptr, NULL); |
| 5675 | if (fp) fclose (fp); | 5686 | if (fp) fclose (fp); |
| 5676 | UNGCPRO; | ||
| 5677 | return 0; | 5687 | return 0; |
| 5678 | } | 5688 | } |
| 5679 | 5689 | ||
| @@ -5687,7 +5697,6 @@ png_load (struct frame *f, struct image *img) | |||
| 5687 | xfree (pixels); | 5697 | xfree (pixels); |
| 5688 | xfree (rows); | 5698 | xfree (rows); |
| 5689 | if (fp) fclose (fp); | 5699 | if (fp) fclose (fp); |
| 5690 | UNGCPRO; | ||
| 5691 | return 0; | 5700 | return 0; |
| 5692 | } | 5701 | } |
| 5693 | 5702 | ||
| @@ -5912,7 +5921,6 @@ png_load (struct frame *f, struct image *img) | |||
| 5912 | x_destroy_x_image (mask_img); | 5921 | x_destroy_x_image (mask_img); |
| 5913 | } | 5922 | } |
| 5914 | 5923 | ||
| 5915 | UNGCPRO; | ||
| 5916 | return 1; | 5924 | return 1; |
| 5917 | } | 5925 | } |
| 5918 | 5926 | ||
| @@ -6313,13 +6321,10 @@ jpeg_load (struct frame *f, struct image *img) | |||
| 6313 | int rc; | 6321 | int rc; |
| 6314 | unsigned long *colors; | 6322 | unsigned long *colors; |
| 6315 | int width, height; | 6323 | int width, height; |
| 6316 | struct gcpro gcpro1; | ||
| 6317 | 6324 | ||
| 6318 | /* Open the JPEG file. */ | 6325 | /* Open the JPEG file. */ |
| 6319 | specified_file = image_spec_value (img->spec, QCfile, NULL); | 6326 | specified_file = image_spec_value (img->spec, QCfile, NULL); |
| 6320 | specified_data = image_spec_value (img->spec, QCdata, NULL); | 6327 | specified_data = image_spec_value (img->spec, QCdata, NULL); |
| 6321 | file = Qnil; | ||
| 6322 | GCPRO1 (file); | ||
| 6323 | 6328 | ||
| 6324 | if (NILP (specified_data)) | 6329 | if (NILP (specified_data)) |
| 6325 | { | 6330 | { |
| @@ -6327,7 +6332,6 @@ jpeg_load (struct frame *f, struct image *img) | |||
| 6327 | if (!STRINGP (file)) | 6332 | if (!STRINGP (file)) |
| 6328 | { | 6333 | { |
| 6329 | image_error ("Cannot find image file `%s'", specified_file, Qnil); | 6334 | image_error ("Cannot find image file `%s'", specified_file, Qnil); |
| 6330 | UNGCPRO; | ||
| 6331 | return 0; | 6335 | return 0; |
| 6332 | } | 6336 | } |
| 6333 | 6337 | ||
| @@ -6335,10 +6339,14 @@ jpeg_load (struct frame *f, struct image *img) | |||
| 6335 | if (fp == NULL) | 6339 | if (fp == NULL) |
| 6336 | { | 6340 | { |
| 6337 | image_error ("Cannot open `%s'", file, Qnil); | 6341 | image_error ("Cannot open `%s'", file, Qnil); |
| 6338 | UNGCPRO; | ||
| 6339 | return 0; | 6342 | return 0; |
| 6340 | } | 6343 | } |
| 6341 | } | 6344 | } |
| 6345 | else if (!STRINGP (specified_data)) | ||
| 6346 | { | ||
| 6347 | image_error ("Invalid image data `%s'", specified_data, Qnil); | ||
| 6348 | return 0; | ||
| 6349 | } | ||
| 6342 | 6350 | ||
| 6343 | /* Customize libjpeg's error handling to call my_error_exit when an | 6351 | /* Customize libjpeg's error handling to call my_error_exit when an |
| 6344 | error is detected. This function will perform a longjmp. | 6352 | error is detected. This function will perform a longjmp. |
| @@ -6367,8 +6375,6 @@ jpeg_load (struct frame *f, struct image *img) | |||
| 6367 | 6375 | ||
| 6368 | /* Free pixmap and colors. */ | 6376 | /* Free pixmap and colors. */ |
| 6369 | x_clear_image (f, img); | 6377 | x_clear_image (f, img); |
| 6370 | |||
| 6371 | UNGCPRO; | ||
| 6372 | return 0; | 6378 | return 0; |
| 6373 | } | 6379 | } |
| 6374 | 6380 | ||
| @@ -6466,7 +6472,6 @@ jpeg_load (struct frame *f, struct image *img) | |||
| 6466 | /* Put the image into the pixmap. */ | 6472 | /* Put the image into the pixmap. */ |
| 6467 | x_put_x_image (f, ximg, img->pixmap, width, height); | 6473 | x_put_x_image (f, ximg, img->pixmap, width, height); |
| 6468 | x_destroy_x_image (ximg); | 6474 | x_destroy_x_image (ximg); |
| 6469 | UNGCPRO; | ||
| 6470 | return 1; | 6475 | return 1; |
| 6471 | } | 6476 | } |
| 6472 | 6477 | ||
| @@ -6741,14 +6746,11 @@ tiff_load (struct frame *f, struct image *img) | |||
| 6741 | uint32 *buf; | 6746 | uint32 *buf; |
| 6742 | int rc, rc2; | 6747 | int rc, rc2; |
| 6743 | XImagePtr ximg; | 6748 | XImagePtr ximg; |
| 6744 | struct gcpro gcpro1; | ||
| 6745 | tiff_memory_source memsrc; | 6749 | tiff_memory_source memsrc; |
| 6746 | Lisp_Object image; | 6750 | Lisp_Object image; |
| 6747 | 6751 | ||
| 6748 | specified_file = image_spec_value (img->spec, QCfile, NULL); | 6752 | specified_file = image_spec_value (img->spec, QCfile, NULL); |
| 6749 | specified_data = image_spec_value (img->spec, QCdata, NULL); | 6753 | specified_data = image_spec_value (img->spec, QCdata, NULL); |
| 6750 | file = Qnil; | ||
| 6751 | GCPRO1 (file); | ||
| 6752 | 6754 | ||
| 6753 | fn_TIFFSetErrorHandler (tiff_error_handler); | 6755 | fn_TIFFSetErrorHandler (tiff_error_handler); |
| 6754 | fn_TIFFSetWarningHandler (tiff_warning_handler); | 6756 | fn_TIFFSetWarningHandler (tiff_warning_handler); |
| @@ -6760,7 +6762,6 @@ tiff_load (struct frame *f, struct image *img) | |||
| 6760 | if (!STRINGP (file)) | 6762 | if (!STRINGP (file)) |
| 6761 | { | 6763 | { |
| 6762 | image_error ("Cannot find image file `%s'", specified_file, Qnil); | 6764 | image_error ("Cannot find image file `%s'", specified_file, Qnil); |
| 6763 | UNGCPRO; | ||
| 6764 | return 0; | 6765 | return 0; |
| 6765 | } | 6766 | } |
| 6766 | 6767 | ||
| @@ -6770,12 +6771,17 @@ tiff_load (struct frame *f, struct image *img) | |||
| 6770 | if (tiff == NULL) | 6771 | if (tiff == NULL) |
| 6771 | { | 6772 | { |
| 6772 | image_error ("Cannot open `%s'", file, Qnil); | 6773 | image_error ("Cannot open `%s'", file, Qnil); |
| 6773 | UNGCPRO; | ||
| 6774 | return 0; | 6774 | return 0; |
| 6775 | } | 6775 | } |
| 6776 | } | 6776 | } |
| 6777 | else | 6777 | else |
| 6778 | { | 6778 | { |
| 6779 | if (!STRINGP (specified_data)) | ||
| 6780 | { | ||
| 6781 | image_error ("Invalid image data `%s'", specified_data, Qnil); | ||
| 6782 | return 0; | ||
| 6783 | } | ||
| 6784 | |||
| 6779 | /* Memory source! */ | 6785 | /* Memory source! */ |
| 6780 | memsrc.bytes = SDATA (specified_data); | 6786 | memsrc.bytes = SDATA (specified_data); |
| 6781 | memsrc.len = SBYTES (specified_data); | 6787 | memsrc.len = SBYTES (specified_data); |
| @@ -6794,7 +6800,6 @@ tiff_load (struct frame *f, struct image *img) | |||
| 6794 | if (!tiff) | 6800 | if (!tiff) |
| 6795 | { | 6801 | { |
| 6796 | image_error ("Cannot open memory source for `%s'", img->spec, Qnil); | 6802 | image_error ("Cannot open memory source for `%s'", img->spec, Qnil); |
| 6797 | UNGCPRO; | ||
| 6798 | return 0; | 6803 | return 0; |
| 6799 | } | 6804 | } |
| 6800 | } | 6805 | } |
| @@ -6808,7 +6813,6 @@ tiff_load (struct frame *f, struct image *img) | |||
| 6808 | image_error ("Invalid image number `%s' in image `%s'", | 6813 | image_error ("Invalid image number `%s' in image `%s'", |
| 6809 | image, img->spec); | 6814 | image, img->spec); |
| 6810 | fn_TIFFClose (tiff); | 6815 | fn_TIFFClose (tiff); |
| 6811 | UNGCPRO; | ||
| 6812 | return 0; | 6816 | return 0; |
| 6813 | } | 6817 | } |
| 6814 | } | 6818 | } |
| @@ -6822,7 +6826,6 @@ tiff_load (struct frame *f, struct image *img) | |||
| 6822 | { | 6826 | { |
| 6823 | image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); | 6827 | image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); |
| 6824 | fn_TIFFClose (tiff); | 6828 | fn_TIFFClose (tiff); |
| 6825 | UNGCPRO; | ||
| 6826 | return 0; | 6829 | return 0; |
| 6827 | } | 6830 | } |
| 6828 | 6831 | ||
| @@ -6844,7 +6847,6 @@ tiff_load (struct frame *f, struct image *img) | |||
| 6844 | { | 6847 | { |
| 6845 | image_error ("Error reading TIFF image `%s'", img->spec, Qnil); | 6848 | image_error ("Error reading TIFF image `%s'", img->spec, Qnil); |
| 6846 | xfree (buf); | 6849 | xfree (buf); |
| 6847 | UNGCPRO; | ||
| 6848 | return 0; | 6850 | return 0; |
| 6849 | } | 6851 | } |
| 6850 | 6852 | ||
| @@ -6852,7 +6854,6 @@ tiff_load (struct frame *f, struct image *img) | |||
| 6852 | if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) | 6854 | if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) |
| 6853 | { | 6855 | { |
| 6854 | xfree (buf); | 6856 | xfree (buf); |
| 6855 | UNGCPRO; | ||
| 6856 | return 0; | 6857 | return 0; |
| 6857 | } | 6858 | } |
| 6858 | 6859 | ||
| @@ -6893,7 +6894,6 @@ tiff_load (struct frame *f, struct image *img) | |||
| 6893 | x_destroy_x_image (ximg); | 6894 | x_destroy_x_image (ximg); |
| 6894 | xfree (buf); | 6895 | xfree (buf); |
| 6895 | 6896 | ||
| 6896 | UNGCPRO; | ||
| 6897 | return 1; | 6897 | return 1; |
| 6898 | } | 6898 | } |
| 6899 | 6899 | ||
| @@ -7099,7 +7099,6 @@ gif_load (struct frame *f, struct image *img) | |||
| 7099 | ColorMapObject *gif_color_map; | 7099 | ColorMapObject *gif_color_map; |
| 7100 | unsigned long pixel_colors[256]; | 7100 | unsigned long pixel_colors[256]; |
| 7101 | GifFileType *gif; | 7101 | GifFileType *gif; |
| 7102 | struct gcpro gcpro1; | ||
| 7103 | Lisp_Object image; | 7102 | Lisp_Object image; |
| 7104 | int ino, image_height, image_width; | 7103 | int ino, image_height, image_width; |
| 7105 | gif_memory_source memsrc; | 7104 | gif_memory_source memsrc; |
| @@ -7107,8 +7106,6 @@ gif_load (struct frame *f, struct image *img) | |||
| 7107 | 7106 | ||
| 7108 | specified_file = image_spec_value (img->spec, QCfile, NULL); | 7107 | specified_file = image_spec_value (img->spec, QCfile, NULL); |
| 7109 | specified_data = image_spec_value (img->spec, QCdata, NULL); | 7108 | specified_data = image_spec_value (img->spec, QCdata, NULL); |
| 7110 | file = Qnil; | ||
| 7111 | GCPRO1 (file); | ||
| 7112 | 7109 | ||
| 7113 | if (NILP (specified_data)) | 7110 | if (NILP (specified_data)) |
| 7114 | { | 7111 | { |
| @@ -7116,7 +7113,6 @@ gif_load (struct frame *f, struct image *img) | |||
| 7116 | if (!STRINGP (file)) | 7113 | if (!STRINGP (file)) |
| 7117 | { | 7114 | { |
| 7118 | image_error ("Cannot find image file `%s'", specified_file, Qnil); | 7115 | image_error ("Cannot find image file `%s'", specified_file, Qnil); |
| 7119 | UNGCPRO; | ||
| 7120 | return 0; | 7116 | return 0; |
| 7121 | } | 7117 | } |
| 7122 | 7118 | ||
| @@ -7126,12 +7122,17 @@ gif_load (struct frame *f, struct image *img) | |||
| 7126 | if (gif == NULL) | 7122 | if (gif == NULL) |
| 7127 | { | 7123 | { |
| 7128 | image_error ("Cannot open `%s'", file, Qnil); | 7124 | image_error ("Cannot open `%s'", file, Qnil); |
| 7129 | UNGCPRO; | ||
| 7130 | return 0; | 7125 | return 0; |
| 7131 | } | 7126 | } |
| 7132 | } | 7127 | } |
| 7133 | else | 7128 | else |
| 7134 | { | 7129 | { |
| 7130 | if (!STRINGP (specified_data)) | ||
| 7131 | { | ||
| 7132 | image_error ("Invalid image data `%s'", specified_data, Qnil); | ||
| 7133 | return 0; | ||
| 7134 | } | ||
| 7135 | |||
| 7135 | /* Read from memory! */ | 7136 | /* Read from memory! */ |
| 7136 | current_gif_memory_src = &memsrc; | 7137 | current_gif_memory_src = &memsrc; |
| 7137 | memsrc.bytes = SDATA (specified_data); | 7138 | memsrc.bytes = SDATA (specified_data); |
| @@ -7143,7 +7144,6 @@ gif_load (struct frame *f, struct image *img) | |||
| 7143 | if (!gif) | 7144 | if (!gif) |
| 7144 | { | 7145 | { |
| 7145 | image_error ("Cannot open memory source `%s'", img->spec, Qnil); | 7146 | image_error ("Cannot open memory source `%s'", img->spec, Qnil); |
| 7146 | UNGCPRO; | ||
| 7147 | return 0; | 7147 | return 0; |
| 7148 | } | 7148 | } |
| 7149 | } | 7149 | } |
| @@ -7153,7 +7153,6 @@ gif_load (struct frame *f, struct image *img) | |||
| 7153 | { | 7153 | { |
| 7154 | image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); | 7154 | image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); |
| 7155 | fn_DGifCloseFile (gif); | 7155 | fn_DGifCloseFile (gif); |
| 7156 | UNGCPRO; | ||
| 7157 | return 0; | 7156 | return 0; |
| 7158 | } | 7157 | } |
| 7159 | 7158 | ||
| @@ -7163,7 +7162,6 @@ gif_load (struct frame *f, struct image *img) | |||
| 7163 | { | 7162 | { |
| 7164 | image_error ("Error reading `%s'", img->spec, Qnil); | 7163 | image_error ("Error reading `%s'", img->spec, Qnil); |
| 7165 | fn_DGifCloseFile (gif); | 7164 | fn_DGifCloseFile (gif); |
| 7166 | UNGCPRO; | ||
| 7167 | return 0; | 7165 | return 0; |
| 7168 | } | 7166 | } |
| 7169 | 7167 | ||
| @@ -7174,7 +7172,6 @@ gif_load (struct frame *f, struct image *img) | |||
| 7174 | image_error ("Invalid image number `%s' in image `%s'", | 7172 | image_error ("Invalid image number `%s' in image `%s'", |
| 7175 | image, img->spec); | 7173 | image, img->spec); |
| 7176 | fn_DGifCloseFile (gif); | 7174 | fn_DGifCloseFile (gif); |
| 7177 | UNGCPRO; | ||
| 7178 | return 0; | 7175 | return 0; |
| 7179 | } | 7176 | } |
| 7180 | 7177 | ||
| @@ -7196,7 +7193,6 @@ gif_load (struct frame *f, struct image *img) | |||
| 7196 | { | 7193 | { |
| 7197 | image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); | 7194 | image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); |
| 7198 | fn_DGifCloseFile (gif); | 7195 | fn_DGifCloseFile (gif); |
| 7199 | UNGCPRO; | ||
| 7200 | return 0; | 7196 | return 0; |
| 7201 | } | 7197 | } |
| 7202 | 7198 | ||
| @@ -7204,7 +7200,6 @@ gif_load (struct frame *f, struct image *img) | |||
| 7204 | if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) | 7200 | if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) |
| 7205 | { | 7201 | { |
| 7206 | fn_DGifCloseFile (gif); | 7202 | fn_DGifCloseFile (gif); |
| 7207 | UNGCPRO; | ||
| 7208 | return 0; | 7203 | return 0; |
| 7209 | } | 7204 | } |
| 7210 | 7205 | ||
| @@ -7323,7 +7318,6 @@ gif_load (struct frame *f, struct image *img) | |||
| 7323 | x_put_x_image (f, ximg, img->pixmap, width, height); | 7318 | x_put_x_image (f, ximg, img->pixmap, width, height); |
| 7324 | x_destroy_x_image (ximg); | 7319 | x_destroy_x_image (ximg); |
| 7325 | 7320 | ||
| 7326 | UNGCPRO; | ||
| 7327 | return 1; | 7321 | return 1; |
| 7328 | } | 7322 | } |
| 7329 | 7323 | ||
| @@ -7389,9 +7383,9 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] = | |||
| 7389 | {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, | 7383 | {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
| 7390 | {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, | 7384 | {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
| 7391 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0}, | 7385 | {":background", IMAGE_STRING_OR_NIL_VALUE, 0}, |
| 7392 | {":height", IMAGE_INTEGER_VALUE, 0}, | 7386 | {":height", IMAGE_INTEGER_VALUE, 0}, |
| 7393 | {":width", IMAGE_INTEGER_VALUE, 0}, | 7387 | {":width", IMAGE_INTEGER_VALUE, 0}, |
| 7394 | {":rotation", IMAGE_NUMBER_VALUE, 0}, | 7388 | {":rotation", IMAGE_NUMBER_VALUE, 0}, |
| 7395 | {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0} | 7389 | {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0} |
| 7396 | }; | 7390 | }; |
| 7397 | /* Free X resources of imagemagick image IMG which is used on frame F. */ | 7391 | /* Free X resources of imagemagick image IMG which is used on frame F. */ |
| @@ -7413,7 +7407,7 @@ static int | |||
| 7413 | imagemagick_image_p (Lisp_Object object) | 7407 | imagemagick_image_p (Lisp_Object object) |
| 7414 | { | 7408 | { |
| 7415 | struct image_keyword fmt[IMAGEMAGICK_LAST]; | 7409 | struct image_keyword fmt[IMAGEMAGICK_LAST]; |
| 7416 | bcopy (imagemagick_format, fmt, sizeof fmt); | 7410 | memcpy (fmt, imagemagick_format, sizeof fmt); |
| 7417 | 7411 | ||
| 7418 | if (!parse_image_spec (object, fmt, IMAGEMAGICK_LAST, Qimagemagick)) | 7412 | if (!parse_image_spec (object, fmt, IMAGEMAGICK_LAST, Qimagemagick)) |
| 7419 | return 0; | 7413 | return 0; |
| @@ -7440,7 +7434,7 @@ static int | |||
| 7440 | imagemagick_load_image (/* Pointer to emacs frame structure. */ | 7434 | imagemagick_load_image (/* Pointer to emacs frame structure. */ |
| 7441 | struct frame *f, | 7435 | struct frame *f, |
| 7442 | /* Pointer to emacs image structure. */ | 7436 | /* Pointer to emacs image structure. */ |
| 7443 | struct image *img, | 7437 | struct image *img, |
| 7444 | /* String containing the IMAGEMAGICK data to | 7438 | /* String containing the IMAGEMAGICK data to |
| 7445 | be parsed. */ | 7439 | be parsed. */ |
| 7446 | unsigned char *contents, | 7440 | unsigned char *contents, |
| @@ -7450,8 +7444,8 @@ imagemagick_load_image (/* Pointer to emacs frame structure. */ | |||
| 7450 | contents/size. */ | 7444 | contents/size. */ |
| 7451 | unsigned char *filename) | 7445 | unsigned char *filename) |
| 7452 | { | 7446 | { |
| 7453 | size_t width; | 7447 | unsigned long width; |
| 7454 | size_t height; | 7448 | unsigned long height; |
| 7455 | 7449 | ||
| 7456 | MagickBooleanType | 7450 | MagickBooleanType |
| 7457 | status; | 7451 | status; |
| @@ -7463,52 +7457,52 @@ imagemagick_load_image (/* Pointer to emacs frame structure. */ | |||
| 7463 | int y; | 7457 | int y; |
| 7464 | 7458 | ||
| 7465 | MagickWand *image_wand; | 7459 | MagickWand *image_wand; |
| 7466 | MagickWand *ping_wand; | 7460 | MagickWand *ping_wand; |
| 7467 | PixelIterator *iterator; | 7461 | PixelIterator *iterator; |
| 7468 | PixelWand **pixels; | 7462 | PixelWand **pixels; |
| 7469 | MagickPixelPacket pixel; | 7463 | MagickPixelPacket pixel; |
| 7470 | Lisp_Object image; | 7464 | Lisp_Object image; |
| 7471 | Lisp_Object value; | 7465 | Lisp_Object value; |
| 7472 | Lisp_Object crop, geometry; | 7466 | Lisp_Object crop, geometry; |
| 7473 | long ino; | 7467 | long ino; |
| 7474 | int desired_width, desired_height; | 7468 | int desired_width, desired_height; |
| 7475 | double rotation; | 7469 | double rotation; |
| 7476 | int imagemagick_rendermethod; | 7470 | int imagemagick_rendermethod; |
| 7477 | int pixelwidth; | 7471 | int pixelwidth; |
| 7478 | ImageInfo *image_info; | 7472 | ImageInfo *image_info; |
| 7479 | ExceptionInfo *exception; | 7473 | ExceptionInfo *exception; |
| 7480 | Image * im_image; | 7474 | Image * im_image; |
| 7481 | 7475 | ||
| 7482 | 7476 | ||
| 7483 | /* Handle image index for image types who can contain more than one | 7477 | /* Handle image index for image types who can contain more than one |
| 7484 | image. Interface :index is same as for GIF. First we "ping" the | 7478 | image. Interface :index is same as for GIF. First we "ping" the |
| 7485 | image to see how many sub-images it contains. Pinging is faster | 7479 | image to see how many sub-images it contains. Pinging is faster |
| 7486 | than loading the image to find out things about it. */ | 7480 | than loading the image to find out things about it. */ |
| 7487 | image = image_spec_value (img->spec, QCindex, NULL); | 7481 | image = image_spec_value (img->spec, QCindex, NULL); |
| 7488 | ino = INTEGERP (image) ? XFASTINT (image) : 0; | 7482 | ino = INTEGERP (image) ? XFASTINT (image) : 0; |
| 7489 | ping_wand=NewMagickWand(); | 7483 | ping_wand = NewMagickWand (); |
| 7490 | MagickSetResolution(ping_wand, 2, 2); | 7484 | MagickSetResolution (ping_wand, 2, 2); |
| 7491 | if (filename != NULL) | 7485 | if (filename != NULL) |
| 7492 | { | 7486 | { |
| 7493 | status = MagickPingImage(ping_wand, filename); | 7487 | status = MagickPingImage (ping_wand, filename); |
| 7494 | } | 7488 | } |
| 7495 | else | 7489 | else |
| 7496 | { | 7490 | { |
| 7497 | status = MagickPingImageBlob(ping_wand, contents, size); | 7491 | status = MagickPingImageBlob (ping_wand, contents, size); |
| 7492 | } | ||
| 7493 | |||
| 7494 | if (ino >= MagickGetNumberImages (ping_wand)) | ||
| 7495 | { | ||
| 7496 | image_error ("Invalid image number `%s' in image `%s'", | ||
| 7497 | image, img->spec); | ||
| 7498 | DestroyMagickWand (ping_wand); | ||
| 7499 | return 0; | ||
| 7498 | } | 7500 | } |
| 7499 | |||
| 7500 | if (ino >= MagickGetNumberImages(ping_wand)) | ||
| 7501 | { | ||
| 7502 | image_error ("Invalid image number `%s' in image `%s'", | ||
| 7503 | image, img->spec); | ||
| 7504 | UNGCPRO; | ||
| 7505 | return 0; | ||
| 7506 | } | ||
| 7507 | 7501 | ||
| 7508 | if (MagickGetNumberImages(ping_wand) > 1) | 7502 | if (MagickGetNumberImages(ping_wand) > 1) |
| 7509 | img->data.lisp_val = | 7503 | img->data.lisp_val = |
| 7510 | Fcons (Qcount, | 7504 | Fcons (Qcount, |
| 7511 | Fcons (make_number (MagickGetNumberImages(ping_wand)), | 7505 | Fcons (make_number (MagickGetNumberImages (ping_wand)), |
| 7512 | img->data.lisp_val)); | 7506 | img->data.lisp_val)); |
| 7513 | 7507 | ||
| 7514 | DestroyMagickWand (ping_wand); | 7508 | DestroyMagickWand (ping_wand); |
| @@ -7517,21 +7511,21 @@ imagemagick_load_image (/* Pointer to emacs frame structure. */ | |||
| 7517 | 7511 | ||
| 7518 | if (filename != NULL) | 7512 | if (filename != NULL) |
| 7519 | { | 7513 | { |
| 7520 | image_info=CloneImageInfo((ImageInfo *) NULL); | 7514 | image_info = CloneImageInfo ((ImageInfo *) NULL); |
| 7521 | (void) strcpy(image_info->filename, filename); | 7515 | (void) strcpy (image_info->filename, filename); |
| 7522 | image_info -> number_scenes = 1; | 7516 | image_info->number_scenes = 1; |
| 7523 | image_info -> scene = ino; | 7517 | image_info->scene = ino; |
| 7524 | exception=AcquireExceptionInfo(); | 7518 | exception = AcquireExceptionInfo (); |
| 7525 | 7519 | ||
| 7526 | im_image = ReadImage (image_info, exception); | 7520 | im_image = ReadImage (image_info, exception); |
| 7527 | CatchException(exception); | 7521 | CatchException (exception); |
| 7528 | 7522 | ||
| 7529 | image_wand = NewMagickWandFromImage(im_image); | 7523 | image_wand = NewMagickWandFromImage (im_image); |
| 7530 | } | 7524 | } |
| 7531 | else | 7525 | else |
| 7532 | { | 7526 | { |
| 7533 | image_wand = NewMagickWand(); | 7527 | image_wand = NewMagickWand (); |
| 7534 | status = MagickReadImageBlob(image_wand, contents, size); | 7528 | status = MagickReadImageBlob (image_wand, contents, size); |
| 7535 | } | 7529 | } |
| 7536 | image_error ("im read failed", Qnil, Qnil); | 7530 | image_error ("im read failed", Qnil, Qnil); |
| 7537 | if (status == MagickFalse) goto imagemagick_error; | 7531 | if (status == MagickFalse) goto imagemagick_error; |
| @@ -7552,44 +7546,56 @@ imagemagick_load_image (/* Pointer to emacs frame structure. */ | |||
| 7552 | if(desired_width != -1 && desired_height == -1) | 7546 | if(desired_width != -1 && desired_height == -1) |
| 7553 | { | 7547 | { |
| 7554 | /* w known, calculate h. */ | 7548 | /* w known, calculate h. */ |
| 7555 | desired_height = ( (double)desired_width / width ) * height; | 7549 | desired_height = (double) desired_width / width * height; |
| 7556 | } | 7550 | } |
| 7557 | if(desired_width == -1 && desired_height != -1) | 7551 | if(desired_width == -1 && desired_height != -1) |
| 7558 | { | 7552 | { |
| 7559 | /* h known, calculate w. */ | 7553 | /* h known, calculate w. */ |
| 7560 | desired_width = ( (double)desired_height / height ) * width; | 7554 | desired_width = (double) desired_height / height * width; |
| 7561 | } | 7555 | } |
| 7562 | if(desired_width != -1 && desired_height != -1) | 7556 | if(desired_width != -1 && desired_height != -1) |
| 7563 | { | 7557 | { |
| 7564 | status = MagickScaleImage(image_wand, desired_width, desired_height); | 7558 | status = MagickScaleImage (image_wand, desired_width, desired_height); |
| 7565 | if (status == MagickFalse) { | 7559 | if (status == MagickFalse) |
| 7566 | image_error ("Imagemagick scale failed", Qnil, Qnil); | 7560 | { |
| 7567 | goto imagemagick_error; | 7561 | image_error ("Imagemagick scale failed", Qnil, Qnil); |
| 7568 | } | 7562 | goto imagemagick_error; |
| 7563 | } | ||
| 7569 | } | 7564 | } |
| 7570 | 7565 | ||
| 7571 | 7566 | ||
| 7572 | /* crop behaves similar to image slicing in Emacs but is more memory | 7567 | /* crop behaves similar to image slicing in Emacs but is more memory |
| 7573 | efficient */ | 7568 | efficient. */ |
| 7574 | crop = image_spec_value (img->spec, QCcrop, NULL); | 7569 | crop = image_spec_value (img->spec, QCcrop, NULL); |
| 7575 | 7570 | ||
| 7576 | if(CONSP (crop)) | 7571 | if (CONSP (crop) && INTEGERP (XCAR (crop))) |
| 7577 | { | 7572 | { |
| 7578 | /* | 7573 | /* After some testing, it seems MagickCropImage is the fastest |
| 7579 | after some testing, it seems MagickCropImage is the fastest | 7574 | crop function in ImageMagick. This crop function seems to do |
| 7580 | crop function in ImageMagick. This crop function seems to do | ||
| 7581 | less copying than the alternatives, but it still reads the | 7575 | less copying than the alternatives, but it still reads the |
| 7582 | entire image into memory before croping, which is aparently | 7576 | entire image into memory before croping, which is aparently |
| 7583 | difficult to avoid when using imagemagick. */ | 7577 | difficult to avoid when using imagemagick. */ |
| 7584 | 7578 | ||
| 7585 | int w,h,x,y; | 7579 | int w, h, x, y; |
| 7586 | w=XFASTINT(XCAR(crop)); | 7580 | w = XFASTINT (XCAR (crop)); |
| 7587 | h=XFASTINT(XCAR(XCDR(crop))); | 7581 | crop = XCDR (crop); |
| 7588 | x=XFASTINT(XCAR(XCDR(XCDR(crop)))); | 7582 | if (CONSP (crop) && INTEGERP (XCAR (crop))) |
| 7589 | y=XFASTINT(XCAR(XCDR(XCDR(XCDR(crop))))); | 7583 | { |
| 7590 | MagickCropImage(image_wand, w,h, x,y); | 7584 | h = XFASTINT (XCAR (crop)); |
| 7591 | } | 7585 | crop = XCDR (crop); |
| 7592 | 7586 | if (CONSP (crop) && INTEGERP (XCAR (crop))) | |
| 7587 | { | ||
| 7588 | x = XFASTINT (XCAR (crop)); | ||
| 7589 | crop = XCDR (crop); | ||
| 7590 | if (CONSP (crop) && INTEGERP (XCAR (crop))) | ||
| 7591 | { | ||
| 7592 | y = XFASTINT (XCAR (crop)); | ||
| 7593 | MagickCropImage (image_wand, w, h, x, y); | ||
| 7594 | } | ||
| 7595 | } | ||
| 7596 | } | ||
| 7597 | } | ||
| 7598 | |||
| 7593 | /* Furthermore :rotation. we need background color and angle for | 7599 | /* Furthermore :rotation. we need background color and angle for |
| 7594 | rotation. */ | 7600 | rotation. */ |
| 7595 | /* | 7601 | /* |
| @@ -7599,11 +7605,11 @@ imagemagick_load_image (/* Pointer to emacs frame structure. */ | |||
| 7599 | value = image_spec_value (img->spec, QCrotation, NULL); | 7605 | value = image_spec_value (img->spec, QCrotation, NULL); |
| 7600 | if (FLOATP (value)) | 7606 | if (FLOATP (value)) |
| 7601 | { | 7607 | { |
| 7602 | PixelWand* background = NewPixelWand(); | 7608 | PixelWand* background = NewPixelWand (); |
| 7603 | PixelSetColor (background, "#ffffff");/*TODO remove hardcode*/ | 7609 | PixelSetColor (background, "#ffffff");/*TODO remove hardcode*/ |
| 7604 | 7610 | ||
| 7605 | rotation = extract_float (value); | 7611 | rotation = extract_float (value); |
| 7606 | 7612 | ||
| 7607 | status = MagickRotateImage (image_wand, background, rotation); | 7613 | status = MagickRotateImage (image_wand, background, rotation); |
| 7608 | DestroyPixelWand (background); | 7614 | DestroyPixelWand (background); |
| 7609 | if (status == MagickFalse) | 7615 | if (status == MagickFalse) |
| @@ -7612,23 +7618,23 @@ imagemagick_load_image (/* Pointer to emacs frame structure. */ | |||
| 7612 | goto imagemagick_error; | 7618 | goto imagemagick_error; |
| 7613 | } | 7619 | } |
| 7614 | } | 7620 | } |
| 7615 | 7621 | ||
| 7616 | /* Finaly we are done manipulating the image, figure out resulting | 7622 | /* Finaly we are done manipulating the image, figure out resulting |
| 7617 | width, height, and then transfer ownerwship to Emacs. */ | 7623 | width, height, and then transfer ownerwship to Emacs. */ |
| 7618 | height = MagickGetImageHeight (image_wand); | 7624 | height = MagickGetImageHeight (image_wand); |
| 7619 | width = MagickGetImageWidth (image_wand); | 7625 | width = MagickGetImageWidth (image_wand); |
| 7620 | if (status == MagickFalse) | 7626 | if (status == MagickFalse) |
| 7621 | { | 7627 | { |
| 7622 | image_error ("Imagemagick image get size failed", Qnil, Qnil); | 7628 | image_error ("Imagemagick image get size failed", Qnil, Qnil); |
| 7623 | goto imagemagick_error; | 7629 | goto imagemagick_error; |
| 7624 | } | 7630 | } |
| 7625 | 7631 | ||
| 7626 | if (! check_image_size (f, width, height)) | 7632 | if (! check_image_size (f, width, height)) |
| 7627 | { | 7633 | { |
| 7628 | image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); | 7634 | image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); |
| 7629 | goto imagemagick_error; | 7635 | goto imagemagick_error; |
| 7630 | } | 7636 | } |
| 7631 | 7637 | ||
| 7632 | /* We can now get a valid pixel buffer from the imagemagick file, if all | 7638 | /* We can now get a valid pixel buffer from the imagemagick file, if all |
| 7633 | went ok. */ | 7639 | went ok. */ |
| 7634 | 7640 | ||
| @@ -7644,24 +7650,24 @@ imagemagick_load_image (/* Pointer to emacs frame structure. */ | |||
| 7644 | image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil); | 7650 | image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil); |
| 7645 | goto imagemagick_error; | 7651 | goto imagemagick_error; |
| 7646 | } | 7652 | } |
| 7647 | 7653 | ||
| 7648 | /* Copy imagegmagick image to x with primitive yet robust pixel | 7654 | /* Copy imagegmagick image to x with primitive yet robust pixel |
| 7649 | pusher loop. This has been tested a lot with many different | 7655 | pusher loop. This has been tested a lot with many different |
| 7650 | images. */ | 7656 | images. */ |
| 7651 | 7657 | ||
| 7652 | /* Copy pixels from the imagemagick image structure to the x image map. */ | 7658 | /* Copy pixels from the imagemagick image structure to the x image map. */ |
| 7653 | iterator = NewPixelIterator (image_wand); | 7659 | iterator = NewPixelIterator (image_wand); |
| 7654 | if ((iterator == (PixelIterator *) NULL)) | 7660 | if (iterator == (PixelIterator *) NULL) |
| 7655 | { | 7661 | { |
| 7656 | image_error ("Imagemagick pixel iterator creation failed", | 7662 | image_error ("Imagemagick pixel iterator creation failed", |
| 7657 | Qnil, Qnil); | 7663 | Qnil, Qnil); |
| 7658 | goto imagemagick_error; | 7664 | goto imagemagick_error; |
| 7659 | } | 7665 | } |
| 7660 | 7666 | ||
| 7661 | for (y = 0; y < (long) MagickGetImageHeight(image_wand); y++) | 7667 | for (y = 0; y < (long) MagickGetImageHeight (image_wand); y++) |
| 7662 | { | 7668 | { |
| 7663 | pixels = PixelGetNextIteratorRow (iterator, &width); | 7669 | pixels = PixelGetNextIteratorRow (iterator, &width); |
| 7664 | if ((pixels == (PixelWand **) NULL)) | 7670 | if (pixels == (PixelWand **) NULL) |
| 7665 | break; | 7671 | break; |
| 7666 | for (x = 0; x < (long) width; x++) | 7672 | for (x = 0; x < (long) width; x++) |
| 7667 | { | 7673 | { |
| @@ -7685,12 +7691,13 @@ imagemagick_load_image (/* Pointer to emacs frame structure. */ | |||
| 7685 | char* exportdepth = imagedepth <= 8 ? "I" : "BGRP";/*"RGBP";*/ | 7691 | char* exportdepth = imagedepth <= 8 ? "I" : "BGRP";/*"RGBP";*/ |
| 7686 | /* Try to create a x pixmap to hold the imagemagick pixmap. */ | 7692 | /* Try to create a x pixmap to hold the imagemagick pixmap. */ |
| 7687 | if (!x_create_x_image_and_pixmap (f, width, height, imagedepth, | 7693 | if (!x_create_x_image_and_pixmap (f, width, height, imagedepth, |
| 7688 | &ximg, &img->pixmap)){ | 7694 | &ximg, &img->pixmap)) |
| 7689 | image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil); | 7695 | { |
| 7690 | goto imagemagick_error; | 7696 | image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil); |
| 7691 | } | 7697 | goto imagemagick_error; |
| 7698 | } | ||
| 7699 | |||
| 7692 | 7700 | ||
| 7693 | |||
| 7694 | /* Oddly, the below code doesnt seem to work:*/ | 7701 | /* Oddly, the below code doesnt seem to work:*/ |
| 7695 | /* switch(ximg->bitmap_unit){ */ | 7702 | /* switch(ximg->bitmap_unit){ */ |
| 7696 | /* case 8: */ | 7703 | /* case 8: */ |
| @@ -7711,20 +7718,20 @@ imagemagick_load_image (/* Pointer to emacs frame structure. */ | |||
| 7711 | seems about 3 times as fast as pixel pushing(not carefully measured) | 7718 | seems about 3 times as fast as pixel pushing(not carefully measured) |
| 7712 | */ | 7719 | */ |
| 7713 | pixelwidth = CharPixel;/*??? TODO figure out*/ | 7720 | pixelwidth = CharPixel;/*??? TODO figure out*/ |
| 7714 | #ifdef HAVE_MAGICKEXPORTIMAGEPIXELS | 7721 | #ifdef HAVE_MAGICKEXPORTIMAGEPIXELS |
| 7715 | MagickExportImagePixels(image_wand, | 7722 | MagickExportImagePixels (image_wand, |
| 7716 | 0, 0, | 7723 | 0, 0, |
| 7717 | width, height, | 7724 | width, height, |
| 7718 | exportdepth, | 7725 | exportdepth, |
| 7719 | pixelwidth, | 7726 | pixelwidth, |
| 7720 | /*&(img->pixmap));*/ | 7727 | /*&(img->pixmap));*/ |
| 7721 | ximg->data); | 7728 | ximg->data); |
| 7722 | #else | 7729 | #else |
| 7723 | image_error("You dont have MagickExportImagePixels, upgrade ImageMagick!", | 7730 | image_error ("You dont have MagickExportImagePixels, upgrade ImageMagick!", |
| 7724 | Qnil, Qnil); | 7731 | Qnil, Qnil); |
| 7725 | #endif | 7732 | #endif |
| 7726 | } | 7733 | } |
| 7727 | 7734 | ||
| 7728 | 7735 | ||
| 7729 | #ifdef COLOR_TABLE_SUPPORT | 7736 | #ifdef COLOR_TABLE_SUPPORT |
| 7730 | /* Remember colors allocated for this image. */ | 7737 | /* Remember colors allocated for this image. */ |
| @@ -7770,20 +7777,14 @@ imagemagick_load (struct frame *f, | |||
| 7770 | if (STRINGP (file_name)) | 7777 | if (STRINGP (file_name)) |
| 7771 | { | 7778 | { |
| 7772 | Lisp_Object file; | 7779 | Lisp_Object file; |
| 7773 | unsigned char *contents; | ||
| 7774 | int size; | ||
| 7775 | struct gcpro gcpro1; | ||
| 7776 | 7780 | ||
| 7777 | file = x_find_image_file (file_name); | 7781 | file = x_find_image_file (file_name); |
| 7778 | GCPRO1 (file); | ||
| 7779 | if (!STRINGP (file)) | 7782 | if (!STRINGP (file)) |
| 7780 | { | 7783 | { |
| 7781 | image_error ("Cannot find image file `%s'", file_name, Qnil); | 7784 | image_error ("Cannot find image file `%s'", file_name, Qnil); |
| 7782 | UNGCPRO; | ||
| 7783 | return 0; | 7785 | return 0; |
| 7784 | } | 7786 | } |
| 7785 | success_p = imagemagick_load_image (f, img, 0, 0, SDATA(file_name)); | 7787 | success_p = imagemagick_load_image (f, img, 0, 0, SDATA (file)); |
| 7786 | UNGCPRO; | ||
| 7787 | } | 7788 | } |
| 7788 | /* Else its not a file, its a lisp object. Load the image from a | 7789 | /* Else its not a file, its a lisp object. Load the image from a |
| 7789 | lisp object rather than a file. */ | 7790 | lisp object rather than a file. */ |
| @@ -7792,6 +7793,11 @@ imagemagick_load (struct frame *f, | |||
| 7792 | Lisp_Object data; | 7793 | Lisp_Object data; |
| 7793 | 7794 | ||
| 7794 | data = image_spec_value (img->spec, QCdata, NULL); | 7795 | data = image_spec_value (img->spec, QCdata, NULL); |
| 7796 | if (!STRINGP (data)) | ||
| 7797 | { | ||
| 7798 | image_error ("Invalid image data `%s'", data, Qnil); | ||
| 7799 | return 0; | ||
| 7800 | } | ||
| 7795 | success_p = imagemagick_load_image (f, img, SDATA (data), | 7801 | success_p = imagemagick_load_image (f, img, SDATA (data), |
| 7796 | SBYTES (data), NULL); | 7802 | SBYTES (data), NULL); |
| 7797 | } | 7803 | } |
| @@ -7823,16 +7829,16 @@ static struct image_type imagemagick_type = | |||
| 7823 | 7829 | ||
| 7824 | 7830 | ||
| 7825 | 7831 | ||
| 7826 | DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0, | 7832 | DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0, |
| 7827 | doc: /* Return image file types supported by ImageMagick. | 7833 | doc: /* Return image file types supported by ImageMagick. |
| 7828 | Since ImageMagick recognizes a lot of file-types that clash with Emacs, | 7834 | Since ImageMagick recognizes a lot of file-types that clash with Emacs, |
| 7829 | such as .c, we want to be able to alter the list at the lisp level. */) | 7835 | such as .c, we want to be able to alter the list at the lisp level. */) |
| 7830 | (void) | 7836 | (void) |
| 7831 | { | 7837 | { |
| 7832 | Lisp_Object typelist = Qnil; | 7838 | Lisp_Object typelist = Qnil; |
| 7833 | size_t numf; | 7839 | unsigned long numf; |
| 7834 | ExceptionInfo ex; | 7840 | ExceptionInfo ex; |
| 7835 | char** imtypes = GetMagickList ("*", &numf, &ex); | 7841 | char **imtypes = GetMagickList ("*", &numf, &ex); |
| 7836 | int i; | 7842 | int i; |
| 7837 | Lisp_Object Qimagemagicktype; | 7843 | Lisp_Object Qimagemagicktype; |
| 7838 | for (i = 0; i < numf; i++) | 7844 | for (i = 0; i < numf; i++) |
| @@ -7842,7 +7848,7 @@ DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0, | |||
| 7842 | } | 7848 | } |
| 7843 | return typelist; | 7849 | return typelist; |
| 7844 | } | 7850 | } |
| 7845 | 7851 | ||
| 7846 | #endif /* defined (HAVE_IMAGEMAGICK) */ | 7852 | #endif /* defined (HAVE_IMAGEMAGICK) */ |
| 7847 | 7853 | ||
| 7848 | 7854 | ||
| @@ -8038,14 +8044,11 @@ svg_load (struct frame *f, struct image *img) | |||
| 8038 | Lisp_Object file; | 8044 | Lisp_Object file; |
| 8039 | unsigned char *contents; | 8045 | unsigned char *contents; |
| 8040 | int size; | 8046 | int size; |
| 8041 | struct gcpro gcpro1; | ||
| 8042 | 8047 | ||
| 8043 | file = x_find_image_file (file_name); | 8048 | file = x_find_image_file (file_name); |
| 8044 | GCPRO1 (file); | ||
| 8045 | if (!STRINGP (file)) | 8049 | if (!STRINGP (file)) |
| 8046 | { | 8050 | { |
| 8047 | image_error ("Cannot find image file `%s'", file_name, Qnil); | 8051 | image_error ("Cannot find image file `%s'", file_name, Qnil); |
| 8048 | UNGCPRO; | ||
| 8049 | return 0; | 8052 | return 0; |
| 8050 | } | 8053 | } |
| 8051 | 8054 | ||
| @@ -8054,13 +8057,11 @@ svg_load (struct frame *f, struct image *img) | |||
| 8054 | if (contents == NULL) | 8057 | if (contents == NULL) |
| 8055 | { | 8058 | { |
| 8056 | image_error ("Error loading SVG image `%s'", img->spec, Qnil); | 8059 | image_error ("Error loading SVG image `%s'", img->spec, Qnil); |
| 8057 | UNGCPRO; | ||
| 8058 | return 0; | 8060 | return 0; |
| 8059 | } | 8061 | } |
| 8060 | /* If the file was slurped into memory properly, parse it. */ | 8062 | /* If the file was slurped into memory properly, parse it. */ |
| 8061 | success_p = svg_load_image (f, img, contents, size); | 8063 | success_p = svg_load_image (f, img, contents, size); |
| 8062 | xfree (contents); | 8064 | xfree (contents); |
| 8063 | UNGCPRO; | ||
| 8064 | } | 8065 | } |
| 8065 | /* Else its not a file, its a lisp object. Load the image from a | 8066 | /* Else its not a file, its a lisp object. Load the image from a |
| 8066 | lisp object rather than a file. */ | 8067 | lisp object rather than a file. */ |
| @@ -8069,6 +8070,11 @@ svg_load (struct frame *f, struct image *img) | |||
| 8069 | Lisp_Object data; | 8070 | Lisp_Object data; |
| 8070 | 8071 | ||
| 8071 | data = image_spec_value (img->spec, QCdata, NULL); | 8072 | data = image_spec_value (img->spec, QCdata, NULL); |
| 8073 | if (!STRINGP (data)) | ||
| 8074 | { | ||
| 8075 | image_error ("Invalid image data `%s'", data, Qnil); | ||
| 8076 | return 0; | ||
| 8077 | } | ||
| 8072 | success_p = svg_load_image (f, img, SDATA (data), SBYTES (data)); | 8078 | success_p = svg_load_image (f, img, SDATA (data), SBYTES (data)); |
| 8073 | } | 8079 | } |
| 8074 | 8080 | ||
| @@ -8368,7 +8374,6 @@ gs_load (struct frame *f, struct image *img) | |||
| 8368 | { | 8374 | { |
| 8369 | char buffer[100]; | 8375 | char buffer[100]; |
| 8370 | Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width; | 8376 | Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width; |
| 8371 | struct gcpro gcpro1, gcpro2; | ||
| 8372 | Lisp_Object frame; | 8377 | Lisp_Object frame; |
| 8373 | double in_width, in_height; | 8378 | double in_width, in_height; |
| 8374 | Lisp_Object pixel_colors = Qnil; | 8379 | Lisp_Object pixel_colors = Qnil; |
| @@ -8378,10 +8383,10 @@ gs_load (struct frame *f, struct image *img) | |||
| 8378 | = 1/72 in, xdpi and ydpi are stored in the frame's X display | 8383 | = 1/72 in, xdpi and ydpi are stored in the frame's X display |
| 8379 | info. */ | 8384 | info. */ |
| 8380 | pt_width = image_spec_value (img->spec, QCpt_width, NULL); | 8385 | pt_width = image_spec_value (img->spec, QCpt_width, NULL); |
| 8381 | in_width = XFASTINT (pt_width) / 72.0; | 8386 | in_width = INTEGERP (pt_width) ? XFASTINT (pt_width) / 72.0 : 0; |
| 8382 | img->width = in_width * FRAME_X_DISPLAY_INFO (f)->resx; | 8387 | img->width = in_width * FRAME_X_DISPLAY_INFO (f)->resx; |
| 8383 | pt_height = image_spec_value (img->spec, QCpt_height, NULL); | 8388 | pt_height = image_spec_value (img->spec, QCpt_height, NULL); |
| 8384 | in_height = XFASTINT (pt_height) / 72.0; | 8389 | in_height = INTEGERP (pt_height) ? XFASTINT (pt_height) / 72.0 : 0; |
| 8385 | img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy; | 8390 | img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy; |
| 8386 | 8391 | ||
| 8387 | if (!check_image_size (f, img->width, img->height)) | 8392 | if (!check_image_size (f, img->width, img->height)) |
| @@ -8410,8 +8415,6 @@ gs_load (struct frame *f, struct image *img) | |||
| 8410 | if successful. We do not record_unwind_protect here because | 8415 | if successful. We do not record_unwind_protect here because |
| 8411 | other places in redisplay like calling window scroll functions | 8416 | other places in redisplay like calling window scroll functions |
| 8412 | don't either. Let the Lisp loader use `unwind-protect' instead. */ | 8417 | don't either. Let the Lisp loader use `unwind-protect' instead. */ |
| 8413 | GCPRO2 (window_and_pixmap_id, pixel_colors); | ||
| 8414 | |||
| 8415 | sprintf (buffer, "%lu %lu", | 8418 | sprintf (buffer, "%lu %lu", |
| 8416 | (unsigned long) FRAME_X_WINDOW (f), | 8419 | (unsigned long) FRAME_X_WINDOW (f), |
| 8417 | (unsigned long) img->pixmap); | 8420 | (unsigned long) img->pixmap); |
| @@ -8432,7 +8435,6 @@ gs_load (struct frame *f, struct image *img) | |||
| 8432 | make_number (img->height), | 8435 | make_number (img->height), |
| 8433 | window_and_pixmap_id, | 8436 | window_and_pixmap_id, |
| 8434 | pixel_colors); | 8437 | pixel_colors); |
| 8435 | UNGCPRO; | ||
| 8436 | return PROCESSP (img->data.lisp_val); | 8438 | return PROCESSP (img->data.lisp_val); |
| 8437 | } | 8439 | } |
| 8438 | 8440 | ||
| @@ -8622,12 +8624,13 @@ of `image-library-alist', which see). */) | |||
| 8622 | #endif | 8624 | #endif |
| 8623 | 8625 | ||
| 8624 | #if defined (HAVE_IMAGEMAGICK) | 8626 | #if defined (HAVE_IMAGEMAGICK) |
| 8625 | if (EQ (type, Qimagemagick)){ | 8627 | if (EQ (type, Qimagemagick)) |
| 8626 | /* MagickWandGenesis() initalizes the imagemagick library. */ | 8628 | { |
| 8627 | MagickWandGenesis(); | 8629 | /* MagickWandGenesis() initalizes the imagemagick library. */ |
| 8628 | return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions, | 8630 | MagickWandGenesis (); |
| 8629 | libraries); | 8631 | return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions, |
| 8630 | } | 8632 | libraries); |
| 8633 | } | ||
| 8631 | #endif | 8634 | #endif |
| 8632 | 8635 | ||
| 8633 | #ifdef HAVE_GHOSTSCRIPT | 8636 | #ifdef HAVE_GHOSTSCRIPT |
| @@ -8786,7 +8789,7 @@ non-numeric, there is no explicit limit on the size of images. */); | |||
| 8786 | staticpro (&Qimagemagick); | 8789 | staticpro (&Qimagemagick); |
| 8787 | ADD_IMAGE_TYPE (Qimagemagick); | 8790 | ADD_IMAGE_TYPE (Qimagemagick); |
| 8788 | #endif | 8791 | #endif |
| 8789 | 8792 | ||
| 8790 | #if defined (HAVE_RSVG) | 8793 | #if defined (HAVE_RSVG) |
| 8791 | Qsvg = intern_c_string ("svg"); | 8794 | Qsvg = intern_c_string ("svg"); |
| 8792 | staticpro (&Qsvg); | 8795 | staticpro (&Qsvg); |
| @@ -8803,9 +8806,9 @@ non-numeric, there is no explicit limit on the size of images. */); | |||
| 8803 | #endif /* HAVE_RSVG */ | 8806 | #endif /* HAVE_RSVG */ |
| 8804 | 8807 | ||
| 8805 | defsubr (&Sinit_image_library); | 8808 | defsubr (&Sinit_image_library); |
| 8806 | #ifdef HAVE_IMAGEMAGICK | 8809 | #ifdef HAVE_IMAGEMAGICK |
| 8807 | defsubr (&Simagemagick_types); | 8810 | defsubr (&Simagemagick_types); |
| 8808 | #endif | 8811 | #endif |
| 8809 | defsubr (&Sclear_image_cache); | 8812 | defsubr (&Sclear_image_cache); |
| 8810 | defsubr (&Simage_flush); | 8813 | defsubr (&Simage_flush); |
| 8811 | defsubr (&Simage_size); | 8814 | defsubr (&Simage_size); |
| @@ -8836,10 +8839,10 @@ The value can also be nil, meaning the cache is never cleared. | |||
| 8836 | 8839 | ||
| 8837 | The function `clear-image-cache' disregards this variable. */); | 8840 | The function `clear-image-cache' disregards this variable. */); |
| 8838 | Vimage_cache_eviction_delay = make_number (300); | 8841 | Vimage_cache_eviction_delay = make_number (300); |
| 8839 | #ifdef HAVE_IMAGEMAGICK | 8842 | #ifdef HAVE_IMAGEMAGICK |
| 8840 | DEFVAR_LISP ("imagemagick-render-type", &Vimagemagick_render_type, | 8843 | DEFVAR_LISP ("imagemagick-render-type", &Vimagemagick_render_type, |
| 8841 | doc: /* Choose between ImageMagick render methods. */); | 8844 | doc: /* Choose between ImageMagick render methods. */); |
| 8842 | #endif | 8845 | #endif |
| 8843 | 8846 | ||
| 8844 | } | 8847 | } |
| 8845 | 8848 | ||
diff --git a/src/keyboard.c b/src/keyboard.c index 95b7c384355..703d03fafa1 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -1494,6 +1494,11 @@ cancel_hourglass_unwind (Lisp_Object arg) | |||
| 1494 | } | 1494 | } |
| 1495 | #endif | 1495 | #endif |
| 1496 | 1496 | ||
| 1497 | /* FIXME: This is wrong rather than test window-system, we should call | ||
| 1498 | a new set-selection, which will then dispatch to x-set-selection, or | ||
| 1499 | tty-set-selection, or w32-set-selection, ... */ | ||
| 1500 | EXFUN (Fwindow_system, 1); | ||
| 1501 | |||
| 1497 | Lisp_Object | 1502 | Lisp_Object |
| 1498 | command_loop_1 (void) | 1503 | command_loop_1 (void) |
| 1499 | { | 1504 | { |
| @@ -1800,10 +1805,11 @@ command_loop_1 (void) | |||
| 1800 | { | 1805 | { |
| 1801 | /* Even if not deactivating the mark, set PRIMARY if | 1806 | /* Even if not deactivating the mark, set PRIMARY if |
| 1802 | `select-active-regions' is non-nil. */ | 1807 | `select-active-regions' is non-nil. */ |
| 1803 | if ((EQ (Vselect_active_regions, Qonly) | 1808 | if (!NILP (Fwindow_system (Qnil)) |
| 1804 | ? EQ (CAR_SAFE (Vtransient_mark_mode), Qonly) | 1809 | && (EQ (Vselect_active_regions, Qonly) |
| 1805 | : (!NILP (Vselect_active_regions) | 1810 | ? EQ (CAR_SAFE (Vtransient_mark_mode), Qonly) |
| 1806 | && !NILP (Vtransient_mark_mode))) | 1811 | : (!NILP (Vselect_active_regions) |
| 1812 | && !NILP (Vtransient_mark_mode))) | ||
| 1807 | && !EQ (Vthis_command, Qhandle_switch_frame)) | 1813 | && !EQ (Vthis_command, Qhandle_switch_frame)) |
| 1808 | { | 1814 | { |
| 1809 | int beg = XINT (Fmarker_position (current_buffer->mark)); | 1815 | int beg = XINT (Fmarker_position (current_buffer->mark)); |
diff --git a/src/marker.c b/src/marker.c index 911d2e57706..b5ea80562df 100644 --- a/src/marker.c +++ b/src/marker.c | |||
| @@ -806,16 +806,18 @@ marker_byte_position (Lisp_Object marker) | |||
| 806 | return i; | 806 | return i; |
| 807 | } | 807 | } |
| 808 | 808 | ||
| 809 | DEFUN ("copy-marker", Fcopy_marker, Scopy_marker, 1, 2, 0, | 809 | DEFUN ("copy-marker", Fcopy_marker, Scopy_marker, 0, 2, 0, |
| 810 | doc: /* Return a new marker pointing at the same place as MARKER. | 810 | doc: /* Return a new marker pointing at the same place as MARKER. |
| 811 | If argument is a number, makes a new marker pointing | 811 | If argument is a number, makes a new marker pointing |
| 812 | at that position in the current buffer. | 812 | at that position in the current buffer. |
| 813 | If MARKER is not specified, the new marker does not point anywhere. | ||
| 813 | The optional argument TYPE specifies the insertion type of the new marker; | 814 | The optional argument TYPE specifies the insertion type of the new marker; |
| 814 | see `marker-insertion-type'. */) | 815 | see `marker-insertion-type'. */) |
| 815 | (register Lisp_Object marker, Lisp_Object type) | 816 | (register Lisp_Object marker, Lisp_Object type) |
| 816 | { | 817 | { |
| 817 | register Lisp_Object new; | 818 | register Lisp_Object new; |
| 818 | 819 | ||
| 820 | if (!NILP (marker)) | ||
| 819 | CHECK_TYPE (INTEGERP (marker) || MARKERP (marker), Qinteger_or_marker_p, marker); | 821 | CHECK_TYPE (INTEGERP (marker) || MARKERP (marker), Qinteger_or_marker_p, marker); |
| 820 | 822 | ||
| 821 | new = Fmake_marker (); | 823 | new = Fmake_marker (); |
diff --git a/src/nsimage.m b/src/nsimage.m index 13761ba5f71..a42950d1f52 100644 --- a/src/nsimage.m +++ b/src/nsimage.m | |||
| @@ -83,19 +83,21 @@ int | |||
| 83 | ns_load_image (struct frame *f, struct image *img, | 83 | ns_load_image (struct frame *f, struct image *img, |
| 84 | Lisp_Object spec_file, Lisp_Object spec_data) | 84 | Lisp_Object spec_file, Lisp_Object spec_data) |
| 85 | { | 85 | { |
| 86 | EmacsImage *eImg; | 86 | EmacsImage *eImg = nil; |
| 87 | NSSize size; | 87 | NSSize size; |
| 88 | 88 | ||
| 89 | NSTRACE (ns_load_image); | 89 | NSTRACE (ns_load_image); |
| 90 | 90 | ||
| 91 | if (NILP (spec_data)) | 91 | if (STRINGP (spec_file)) |
| 92 | { | 92 | { |
| 93 | eImg = [EmacsImage allocInitFromFile: spec_file]; | 93 | eImg = [EmacsImage allocInitFromFile: spec_file]; |
| 94 | } | 94 | } |
| 95 | else | 95 | else if (STRINGP (spec_data)) |
| 96 | { | 96 | { |
| 97 | NSData *data = [NSData dataWithBytes: SDATA (spec_data) | 97 | NSData *data; |
| 98 | length: SBYTES (spec_data)]; | 98 | |
| 99 | data = [NSData dataWithBytes: SDATA (spec_data) | ||
| 100 | length: SBYTES (spec_data)]; | ||
| 99 | eImg = [[EmacsImage alloc] initWithData: data]; | 101 | eImg = [[EmacsImage alloc] initWithData: data]; |
| 100 | [eImg setPixmapData]; | 102 | [eImg setPixmapData]; |
| 101 | } | 103 | } |
diff --git a/src/nsterm.m b/src/nsterm.m index 2eb84607562..f0efb948ab9 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -2251,6 +2251,11 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, | |||
| 2251 | struct frame *f = WINDOW_XFRAME (w); | 2251 | struct frame *f = WINDOW_XFRAME (w); |
| 2252 | struct glyph *phys_cursor_glyph; | 2252 | struct glyph *phys_cursor_glyph; |
| 2253 | int overspill; | 2253 | int overspill; |
| 2254 | struct glyph *cursor_glyph; | ||
| 2255 | |||
| 2256 | /* If cursor is out of bounds, don't draw garbage. This can happen | ||
| 2257 | in mini-buffer windows when switching between echo area glyphs | ||
| 2258 | and mini-buffer. */ | ||
| 2254 | 2259 | ||
| 2255 | NSTRACE (dumpcursor); | 2260 | NSTRACE (dumpcursor); |
| 2256 | //fprintf(stderr, "drawcursor (%d,%d) activep = %d\tonp = %d\tc_type = %d\twidth = %d\n",x,y, active_p,on_p,cursor_type,cursor_width); | 2261 | //fprintf(stderr, "drawcursor (%d,%d) activep = %d\tonp = %d\tc_type = %d\twidth = %d\n",x,y, active_p,on_p,cursor_type,cursor_width); |
| @@ -2328,6 +2333,13 @@ ns_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, | |||
| 2328 | case BAR_CURSOR: | 2333 | case BAR_CURSOR: |
| 2329 | s = r; | 2334 | s = r; |
| 2330 | s.size.width = min (cursor_width, 2); //FIXME(see above) | 2335 | s.size.width = min (cursor_width, 2); //FIXME(see above) |
| 2336 | |||
| 2337 | /* If the character under cursor is R2L, draw the bar cursor | ||
| 2338 | on the right of its glyph, rather than on the left. */ | ||
| 2339 | cursor_glyph = get_phys_cursor_glyph (w); | ||
| 2340 | if ((cursor_glyph->resolved_level & 1) != 0) | ||
| 2341 | s.origin.x += cursor_glyph->pixel_width - s.size.width; | ||
| 2342 | |||
| 2331 | NSRectFill (s); | 2343 | NSRectFill (s); |
| 2332 | break; | 2344 | break; |
| 2333 | } | 2345 | } |
diff --git a/src/term.c b/src/term.c index d1279498060..f090cdd2792 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -689,7 +689,8 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi | |||
| 689 | encode_terminal_src_size); | 689 | encode_terminal_src_size); |
| 690 | buf = encode_terminal_src + nbytes; | 690 | buf = encode_terminal_src + nbytes; |
| 691 | } | 691 | } |
| 692 | if (char_charset (c, charset_list, NULL)) | 692 | if (CHAR_BYTE8_P (c) |
| 693 | || char_charset (c, charset_list, NULL)) | ||
| 693 | { | 694 | { |
| 694 | /* Store the multibyte form of C at BUF. */ | 695 | /* Store the multibyte form of C at BUF. */ |
| 695 | buf += CHAR_STRING (c, buf); | 696 | buf += CHAR_STRING (c, buf); |
| @@ -1614,18 +1615,15 @@ produce_glyphs (struct it *it) | |||
| 1614 | goto done; | 1615 | goto done; |
| 1615 | } | 1616 | } |
| 1616 | 1617 | ||
| 1617 | /* Maybe translate single-byte characters to multibyte. */ | 1618 | if (it->char_to_display >= 040 && it->char_to_display < 0177) |
| 1618 | it->char_to_display = it->c; | ||
| 1619 | |||
| 1620 | if (it->c >= 040 && it->c < 0177) | ||
| 1621 | { | 1619 | { |
| 1622 | it->pixel_width = it->nglyphs = 1; | 1620 | it->pixel_width = it->nglyphs = 1; |
| 1623 | if (it->glyph_row) | 1621 | if (it->glyph_row) |
| 1624 | append_glyph (it); | 1622 | append_glyph (it); |
| 1625 | } | 1623 | } |
| 1626 | else if (it->c == '\n') | 1624 | else if (it->char_to_display == '\n') |
| 1627 | it->pixel_width = it->nglyphs = 0; | 1625 | it->pixel_width = it->nglyphs = 0; |
| 1628 | else if (it->c == '\t') | 1626 | else if (it->char_to_display == '\t') |
| 1629 | { | 1627 | { |
| 1630 | int absolute_x = (it->current_x | 1628 | int absolute_x = (it->current_x |
| 1631 | + it->continuation_lines_width); | 1629 | + it->continuation_lines_width); |
| @@ -1656,32 +1654,19 @@ produce_glyphs (struct it *it) | |||
| 1656 | it->pixel_width = nspaces; | 1654 | it->pixel_width = nspaces; |
| 1657 | it->nglyphs = nspaces; | 1655 | it->nglyphs = nspaces; |
| 1658 | } | 1656 | } |
| 1659 | else if (CHAR_BYTE8_P (it->c)) | 1657 | else if (CHAR_BYTE8_P (it->char_to_display)) |
| 1660 | { | 1658 | { |
| 1661 | if (unibyte_display_via_language_environment | 1659 | /* Coming here means that we must send the raw 8-bit byte as is |
| 1662 | && (it->c >= 0240)) | 1660 | to the terminal. Although there's no way to know how many |
| 1663 | { | 1661 | columns it occupies on a screen, it is a good assumption that |
| 1664 | it->char_to_display = BYTE8_TO_CHAR (it->c); | 1662 | a single byte code has 1-column width. */ |
| 1665 | it->pixel_width = CHAR_WIDTH (it->char_to_display); | 1663 | it->pixel_width = it->nglyphs = 1; |
| 1666 | it->nglyphs = it->pixel_width; | 1664 | if (it->glyph_row) |
| 1667 | if (it->glyph_row) | 1665 | append_glyph (it); |
| 1668 | append_glyph (it); | ||
| 1669 | } | ||
| 1670 | else | ||
| 1671 | { | ||
| 1672 | /* Coming here means that it->c is from display table, thus | ||
| 1673 | we must send the raw 8-bit byte as is to the terminal. | ||
| 1674 | Although there's no way to know how many columns it | ||
| 1675 | occupies on a screen, it is a good assumption that a | ||
| 1676 | single byte code has 1-column width. */ | ||
| 1677 | it->pixel_width = it->nglyphs = 1; | ||
| 1678 | if (it->glyph_row) | ||
| 1679 | append_glyph (it); | ||
| 1680 | } | ||
| 1681 | } | 1666 | } |
| 1682 | else | 1667 | else |
| 1683 | { | 1668 | { |
| 1684 | it->pixel_width = CHAR_WIDTH (it->c); | 1669 | it->pixel_width = CHAR_WIDTH (it->char_to_display); |
| 1685 | it->nglyphs = it->pixel_width; | 1670 | it->nglyphs = it->pixel_width; |
| 1686 | 1671 | ||
| 1687 | if (it->glyph_row) | 1672 | if (it->glyph_row) |
| @@ -1917,7 +1902,7 @@ produce_special_glyphs (struct it *it, enum display_element_type what) | |||
| 1917 | else | 1902 | else |
| 1918 | abort (); | 1903 | abort (); |
| 1919 | 1904 | ||
| 1920 | temp_it.c = GLYPH_CHAR (glyph); | 1905 | temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph); |
| 1921 | temp_it.face_id = GLYPH_FACE (glyph); | 1906 | temp_it.face_id = GLYPH_FACE (glyph); |
| 1922 | temp_it.len = CHAR_BYTES (temp_it.c); | 1907 | temp_it.len = CHAR_BYTES (temp_it.c); |
| 1923 | 1908 | ||
diff --git a/src/w32uniscribe.c b/src/w32uniscribe.c index 9edd6353ba3..05cc8346a50 100644 --- a/src/w32uniscribe.c +++ b/src/w32uniscribe.c | |||
| @@ -180,17 +180,18 @@ uniscribe_otf_capability (struct font *font) | |||
| 180 | 180 | ||
| 181 | /* Uniscribe implementation of shape for font backend. | 181 | /* Uniscribe implementation of shape for font backend. |
| 182 | 182 | ||
| 183 | Shape text in LGSTRING. See the docstring of `font-make-gstring' | 183 | Shape text in LGSTRING. See the docstring of |
| 184 | for the format of LGSTRING. If the (N+1)th element of LGSTRING | 184 | `composition-get-gstring' for the format of LGSTRING. If the |
| 185 | is nil, input of shaping is from the 1st to (N)th elements. In | 185 | (N+1)th element of LGSTRING is nil, input of shaping is from the |
| 186 | each input glyph, FROM, TO, CHAR, and CODE are already set. | 186 | 1st to (N)th elements. In each input glyph, FROM, TO, CHAR, and |
| 187 | CODE are already set. | ||
| 187 | 188 | ||
| 188 | This function updates all fields of the input glyphs. If the | 189 | This function updates all fields of the input glyphs. If the |
| 189 | output glyphs (M) are more than the input glyphs (N), (N+1)th | 190 | output glyphs (M) are more than the input glyphs (N), (N+1)th |
| 190 | through (M)th elements of LGSTRING are updated possibly by making | 191 | through (M)th elements of LGSTRING are updated possibly by making |
| 191 | a new glyph object and storing it in LGSTRING. If (M) is greater | 192 | a new glyph object and storing it in LGSTRING. If (M) is greater |
| 192 | than the length of LGSTRING, nil should be return. In that case, | 193 | than the length of LGSTRING, nil should be returned. In that case, |
| 193 | this function is called again with the larger LGSTRING. */ | 194 | this function is called again with a larger LGSTRING. */ |
| 194 | static Lisp_Object | 195 | static Lisp_Object |
| 195 | uniscribe_shape (Lisp_Object lgstring) | 196 | uniscribe_shape (Lisp_Object lgstring) |
| 196 | { | 197 | { |
| @@ -217,6 +218,9 @@ uniscribe_shape (Lisp_Object lgstring) | |||
| 217 | max_glyphs = nchars = LGSTRING_GLYPH_LEN (lgstring); | 218 | max_glyphs = nchars = LGSTRING_GLYPH_LEN (lgstring); |
| 218 | done_glyphs = 0; | 219 | done_glyphs = 0; |
| 219 | chars = (wchar_t *) alloca (nchars * sizeof (wchar_t)); | 220 | chars = (wchar_t *) alloca (nchars * sizeof (wchar_t)); |
| 221 | /* FIXME: This loop assumes that characters in the input LGSTRING | ||
| 222 | are all inside the BMP. Need to encode characters beyond the BMP | ||
| 223 | as UTF-16. */ | ||
| 220 | for (i = 0; i < nchars; i++) | 224 | for (i = 0; i < nchars; i++) |
| 221 | { | 225 | { |
| 222 | /* lgstring can be bigger than the number of characters in it, in | 226 | /* lgstring can be bigger than the number of characters in it, in |
| @@ -248,9 +252,6 @@ uniscribe_shape (Lisp_Object lgstring) | |||
| 248 | return Qnil; | 252 | return Qnil; |
| 249 | } | 253 | } |
| 250 | 254 | ||
| 251 | /* TODO: When we get BIDI support, we need to call ScriptLayout here. | ||
| 252 | Requires that we know the surrounding context. */ | ||
| 253 | |||
| 254 | glyphs = alloca (max_glyphs * sizeof (WORD)); | 255 | glyphs = alloca (max_glyphs * sizeof (WORD)); |
| 255 | clusters = alloca (nchars * sizeof (WORD)); | 256 | clusters = alloca (nchars * sizeof (WORD)); |
| 256 | attributes = alloca (max_glyphs * sizeof (SCRIPT_VISATTR)); | 257 | attributes = alloca (max_glyphs * sizeof (SCRIPT_VISATTR)); |
| @@ -259,8 +260,12 @@ uniscribe_shape (Lisp_Object lgstring) | |||
| 259 | 260 | ||
| 260 | for (i = 0; i < nitems; i++) | 261 | for (i = 0; i < nitems; i++) |
| 261 | { | 262 | { |
| 262 | int nglyphs, nchars_in_run, rtl = items[i].a.fRTL ? -1 : 1; | 263 | int nglyphs, nchars_in_run; |
| 263 | nchars_in_run = items[i+1].iCharPos - items[i].iCharPos; | 264 | nchars_in_run = items[i+1].iCharPos - items[i].iCharPos; |
| 265 | /* Force ScriptShape to generate glyphs in the same order as | ||
| 266 | they are in the input LGSTRING, which is in the logical | ||
| 267 | order. */ | ||
| 268 | items[i].a.fLogicalOrder = 1; | ||
| 264 | 269 | ||
| 265 | /* Context may be NULL here, in which case the cache should be | 270 | /* Context may be NULL here, in which case the cache should be |
| 266 | used without needing to select the font. */ | 271 | used without needing to select the font. */ |
| @@ -321,7 +326,7 @@ uniscribe_shape (Lisp_Object lgstring) | |||
| 321 | { | 326 | { |
| 322 | int j, nclusters, from, to; | 327 | int j, nclusters, from, to; |
| 323 | 328 | ||
| 324 | from = rtl > 0 ? 0 : nchars_in_run - 1; | 329 | from = 0; |
| 325 | to = from; | 330 | to = from; |
| 326 | 331 | ||
| 327 | for (j = 0; j < nglyphs; j++) | 332 | for (j = 0; j < nglyphs; j++) |
| @@ -342,22 +347,19 @@ uniscribe_shape (Lisp_Object lgstring) | |||
| 342 | gl = glyphs[j]; | 347 | gl = glyphs[j]; |
| 343 | LGLYPH_SET_CODE (lglyph, gl); | 348 | LGLYPH_SET_CODE (lglyph, gl); |
| 344 | 349 | ||
| 345 | /* Detect clusters, for linking codes back to characters. */ | 350 | /* Detect clusters, for linking codes back to |
| 351 | characters. */ | ||
| 346 | if (attributes[j].fClusterStart) | 352 | if (attributes[j].fClusterStart) |
| 347 | { | 353 | { |
| 348 | while (from >= 0 && from < nchars_in_run | 354 | while (from < nchars_in_run && clusters[from] < j) |
| 349 | && clusters[from] < j) | 355 | from++; |
| 350 | from += rtl; | 356 | if (from >= nchars_in_run) |
| 351 | if (from < 0) | ||
| 352 | from = to = 0; | ||
| 353 | else if (from >= nchars_in_run) | ||
| 354 | from = to = nchars_in_run - 1; | 357 | from = to = nchars_in_run - 1; |
| 355 | else | 358 | else |
| 356 | { | 359 | { |
| 357 | int k; | 360 | int k; |
| 358 | to = rtl > 0 ? nchars_in_run - 1 : 0; | 361 | to = nchars_in_run - 1; |
| 359 | for (k = from + rtl; k >= 0 && k < nchars_in_run; | 362 | for (k = from + 1; k < nchars_in_run; k++) |
| 360 | k += rtl) | ||
| 361 | { | 363 | { |
| 362 | if (clusters[k] > j) | 364 | if (clusters[k] > j) |
| 363 | { | 365 | { |
| @@ -486,6 +488,10 @@ uniscribe_encode_char (struct font *font, int c) | |||
| 486 | SCRIPT_VISATTR attrs[2]; | 488 | SCRIPT_VISATTR attrs[2]; |
| 487 | int nglyphs; | 489 | int nglyphs; |
| 488 | 490 | ||
| 491 | /* Force ScriptShape to generate glyphs in the logical | ||
| 492 | order. */ | ||
| 493 | items[0].a.fLogicalOrder = 1; | ||
| 494 | |||
| 489 | result = ScriptShape (context, &(uniscribe_font->cache), | 495 | result = ScriptShape (context, &(uniscribe_font->cache), |
| 490 | ch, len, 2, &(items[0].a), | 496 | ch, len, 2, &(items[0].a), |
| 491 | glyphs, clusters, attrs, &nglyphs); | 497 | glyphs, clusters, attrs, &nglyphs); |
diff --git a/src/xdisp.c b/src/xdisp.c index efae826755f..c363a3e7a62 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -5798,10 +5798,23 @@ get_next_display_element (struct it *it) | |||
| 5798 | struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte); | 5798 | struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte); |
| 5799 | enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen } | 5799 | enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen } |
| 5800 | nbsp_or_shy = char_is_other; | 5800 | nbsp_or_shy = char_is_other; |
| 5801 | int decoded = it->c; | 5801 | int c = it->c; /* This is the character to display. */ |
| 5802 | |||
| 5803 | if (! it->multibyte_p && ! ASCII_CHAR_P (c)) | ||
| 5804 | { | ||
| 5805 | xassert (SINGLE_BYTE_CHAR_P (c)); | ||
| 5806 | if (unibyte_display_via_language_environment) | ||
| 5807 | { | ||
| 5808 | c = DECODE_CHAR (unibyte, c); | ||
| 5809 | if (c < 0) | ||
| 5810 | c = BYTE8_TO_CHAR (it->c); | ||
| 5811 | } | ||
| 5812 | else | ||
| 5813 | c = BYTE8_TO_CHAR (it->c); | ||
| 5814 | } | ||
| 5802 | 5815 | ||
| 5803 | if (it->dp | 5816 | if (it->dp |
| 5804 | && (dv = DISP_CHAR_VECTOR (it->dp, it->c), | 5817 | && (dv = DISP_CHAR_VECTOR (it->dp, c), |
| 5805 | VECTORP (dv))) | 5818 | VECTORP (dv))) |
| 5806 | { | 5819 | { |
| 5807 | struct Lisp_Vector *v = XVECTOR (dv); | 5820 | struct Lisp_Vector *v = XVECTOR (dv); |
| @@ -5827,21 +5840,10 @@ get_next_display_element (struct it *it) | |||
| 5827 | goto get_next; | 5840 | goto get_next; |
| 5828 | } | 5841 | } |
| 5829 | 5842 | ||
| 5830 | if (unibyte_display_via_language_environment | 5843 | if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display)) |
| 5831 | && !ASCII_CHAR_P (it->c)) | 5844 | nbsp_or_shy = (c == 0xA0 ? char_is_nbsp |
| 5832 | decoded = DECODE_CHAR (unibyte, it->c); | 5845 | : c == 0xAD ? char_is_soft_hyphen |
| 5833 | 5846 | : char_is_other); | |
| 5834 | if (it->c >= 0x80 && ! NILP (Vnobreak_char_display)) | ||
| 5835 | { | ||
| 5836 | if (it->multibyte_p) | ||
| 5837 | nbsp_or_shy = (it->c == 0xA0 ? char_is_nbsp | ||
| 5838 | : it->c == 0xAD ? char_is_soft_hyphen | ||
| 5839 | : char_is_other); | ||
| 5840 | else if (unibyte_display_via_language_environment) | ||
| 5841 | nbsp_or_shy = (decoded == 0xA0 ? char_is_nbsp | ||
| 5842 | : decoded == 0xAD ? char_is_soft_hyphen | ||
| 5843 | : char_is_other); | ||
| 5844 | } | ||
| 5845 | 5847 | ||
| 5846 | /* Translate control characters into `\003' or `^C' form. | 5848 | /* Translate control characters into `\003' or `^C' form. |
| 5847 | Control characters coming from a display table entry are | 5849 | Control characters coming from a display table entry are |
| @@ -5849,27 +5851,23 @@ get_next_display_element (struct it *it) | |||
| 5849 | the translation. This could easily be changed but I | 5851 | the translation. This could easily be changed but I |
| 5850 | don't believe that it is worth doing. | 5852 | don't believe that it is worth doing. |
| 5851 | 5853 | ||
| 5852 | If it->multibyte_p is nonzero, non-printable non-ASCII | 5854 | NBSP and SOFT-HYPEN are property translated too. |
| 5853 | characters are also translated to octal form. | ||
| 5854 | 5855 | ||
| 5855 | If it->multibyte_p is zero, eight-bit characters that | 5856 | Non-printable characters and raw-byte characters are also |
| 5856 | don't have corresponding multibyte char code are also | ||
| 5857 | translated to octal form. */ | 5857 | translated to octal form. */ |
| 5858 | if ((it->c < ' ' | 5858 | if (((c < ' ' || c == 127) /* ASCII control chars */ |
| 5859 | ? (it->area != TEXT_AREA | 5859 | ? (it->area != TEXT_AREA |
| 5860 | /* In mode line, treat \n, \t like other crl chars. */ | 5860 | /* In mode line, treat \n, \t like other crl chars. */ |
| 5861 | || (it->c != '\t' | 5861 | || (c != '\t' |
| 5862 | && it->glyph_row | 5862 | && it->glyph_row |
| 5863 | && (it->glyph_row->mode_line_p || it->avoid_cursor_p)) | 5863 | && (it->glyph_row->mode_line_p || it->avoid_cursor_p)) |
| 5864 | || (it->c != '\n' && it->c != '\t')) | 5864 | || (c != '\n' && c != '\t')) |
| 5865 | : (nbsp_or_shy | 5865 | : (nbsp_or_shy |
| 5866 | || (it->multibyte_p | 5866 | || CHAR_BYTE8_P (c) |
| 5867 | ? ! CHAR_PRINTABLE_P (it->c) | 5867 | || ! CHAR_PRINTABLE_P (c)))) |
| 5868 | : (! unibyte_display_via_language_environment | ||
| 5869 | ? it->c >= 0x80 | ||
| 5870 | : (decoded >= 0x80 && decoded < 0xA0)))))) | ||
| 5871 | { | 5868 | { |
| 5872 | /* IT->c is a control character which must be displayed | 5869 | /* C is a control character, NBSP, SOFT-HYPEN, raw-byte, |
| 5870 | or a non-printable character which must be displayed | ||
| 5873 | either as '\003' or as `^C' where the '\\' and '^' | 5871 | either as '\003' or as `^C' where the '\\' and '^' |
| 5874 | can be defined in the display table. Fill | 5872 | can be defined in the display table. Fill |
| 5875 | IT->ctl_chars with glyphs for what we have to | 5873 | IT->ctl_chars with glyphs for what we have to |
| @@ -5881,7 +5879,7 @@ get_next_display_element (struct it *it) | |||
| 5881 | 5879 | ||
| 5882 | /* Handle control characters with ^. */ | 5880 | /* Handle control characters with ^. */ |
| 5883 | 5881 | ||
| 5884 | if (it->c < 128 && it->ctl_arrow_p) | 5882 | if (ASCII_CHAR_P (c) && it->ctl_arrow_p) |
| 5885 | { | 5883 | { |
| 5886 | int g; | 5884 | int g; |
| 5887 | 5885 | ||
| @@ -5914,7 +5912,7 @@ get_next_display_element (struct it *it) | |||
| 5914 | } | 5912 | } |
| 5915 | 5913 | ||
| 5916 | XSETINT (it->ctl_chars[0], g); | 5914 | XSETINT (it->ctl_chars[0], g); |
| 5917 | XSETINT (it->ctl_chars[1], it->c ^ 0100); | 5915 | XSETINT (it->ctl_chars[1], c ^ 0100); |
| 5918 | ctl_len = 2; | 5916 | ctl_len = 2; |
| 5919 | goto display_control; | 5917 | goto display_control; |
| 5920 | } | 5918 | } |
| @@ -5929,7 +5927,7 @@ get_next_display_element (struct it *it) | |||
| 5929 | face_id = merge_faces (it->f, Qnobreak_space, 0, | 5927 | face_id = merge_faces (it->f, Qnobreak_space, 0, |
| 5930 | it->face_id); | 5928 | it->face_id); |
| 5931 | 5929 | ||
| 5932 | it->c = ' '; | 5930 | c = ' '; |
| 5933 | XSETINT (it->ctl_chars[0], ' '); | 5931 | XSETINT (it->ctl_chars[0], ' '); |
| 5934 | ctl_len = 1; | 5932 | ctl_len = 1; |
| 5935 | goto display_control; | 5933 | goto display_control; |
| @@ -5975,7 +5973,6 @@ get_next_display_element (struct it *it) | |||
| 5975 | if (EQ (Vnobreak_char_display, Qt) | 5973 | if (EQ (Vnobreak_char_display, Qt) |
| 5976 | && nbsp_or_shy == char_is_soft_hyphen) | 5974 | && nbsp_or_shy == char_is_soft_hyphen) |
| 5977 | { | 5975 | { |
| 5978 | it->c = '-'; | ||
| 5979 | XSETINT (it->ctl_chars[0], '-'); | 5976 | XSETINT (it->ctl_chars[0], '-'); |
| 5980 | ctl_len = 1; | 5977 | ctl_len = 1; |
| 5981 | goto display_control; | 5978 | goto display_control; |
| @@ -5987,55 +5984,25 @@ get_next_display_element (struct it *it) | |||
| 5987 | if (nbsp_or_shy) | 5984 | if (nbsp_or_shy) |
| 5988 | { | 5985 | { |
| 5989 | XSETINT (it->ctl_chars[0], escape_glyph); | 5986 | XSETINT (it->ctl_chars[0], escape_glyph); |
| 5990 | it->c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-'); | 5987 | c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-'); |
| 5991 | XSETINT (it->ctl_chars[1], it->c); | 5988 | XSETINT (it->ctl_chars[1], c); |
| 5992 | ctl_len = 2; | 5989 | ctl_len = 2; |
| 5993 | goto display_control; | 5990 | goto display_control; |
| 5994 | } | 5991 | } |
| 5995 | 5992 | ||
| 5996 | { | 5993 | { |
| 5997 | unsigned char str[MAX_MULTIBYTE_LENGTH]; | 5994 | char str[10]; |
| 5998 | int len; | 5995 | int len, i; |
| 5999 | int i; | ||
| 6000 | 5996 | ||
| 6001 | /* Set IT->ctl_chars[0] to the glyph for `\\'. */ | 5997 | if (CHAR_BYTE8_P (c)) |
| 6002 | if (CHAR_BYTE8_P (it->c)) | 5998 | /* Display \200 instead of \17777600. */ |
| 6003 | { | 5999 | c = CHAR_TO_BYTE8 (c); |
| 6004 | str[0] = CHAR_TO_BYTE8 (it->c); | 6000 | len = sprintf (str, "%03o", c); |
| 6005 | len = 1; | ||
| 6006 | } | ||
| 6007 | else if (it->c < 256) | ||
| 6008 | { | ||
| 6009 | str[0] = it->c; | ||
| 6010 | len = 1; | ||
| 6011 | } | ||
| 6012 | else | ||
| 6013 | { | ||
| 6014 | /* It's an invalid character, which shouldn't | ||
| 6015 | happen actually, but due to bugs it may | ||
| 6016 | happen. Let's print the char as is, there's | ||
| 6017 | not much meaningful we can do with it. */ | ||
| 6018 | str[0] = it->c; | ||
| 6019 | str[1] = it->c >> 8; | ||
| 6020 | str[2] = it->c >> 16; | ||
| 6021 | str[3] = it->c >> 24; | ||
| 6022 | len = 4; | ||
| 6023 | } | ||
| 6024 | 6001 | ||
| 6002 | XSETINT (it->ctl_chars[0], escape_glyph); | ||
| 6025 | for (i = 0; i < len; i++) | 6003 | for (i = 0; i < len; i++) |
| 6026 | { | 6004 | XSETINT (it->ctl_chars[i + 1], str[i]); |
| 6027 | int g; | 6005 | ctl_len = len + 1; |
| 6028 | XSETINT (it->ctl_chars[i * 4], escape_glyph); | ||
| 6029 | /* Insert three more glyphs into IT->ctl_chars for | ||
| 6030 | the octal display of the character. */ | ||
| 6031 | g = ((str[i] >> 6) & 7) + '0'; | ||
| 6032 | XSETINT (it->ctl_chars[i * 4 + 1], g); | ||
| 6033 | g = ((str[i] >> 3) & 7) + '0'; | ||
| 6034 | XSETINT (it->ctl_chars[i * 4 + 2], g); | ||
| 6035 | g = (str[i] & 7) + '0'; | ||
| 6036 | XSETINT (it->ctl_chars[i * 4 + 3], g); | ||
| 6037 | } | ||
| 6038 | ctl_len = len * 4; | ||
| 6039 | } | 6006 | } |
| 6040 | 6007 | ||
| 6041 | display_control: | 6008 | display_control: |
| @@ -6050,6 +6017,11 @@ get_next_display_element (struct it *it) | |||
| 6050 | it->ellipsis_p = 0; | 6017 | it->ellipsis_p = 0; |
| 6051 | goto get_next; | 6018 | goto get_next; |
| 6052 | } | 6019 | } |
| 6020 | it->char_to_display = c; | ||
| 6021 | } | ||
| 6022 | else if (success_p) | ||
| 6023 | { | ||
| 6024 | it->char_to_display = it->c; | ||
| 6053 | } | 6025 | } |
| 6054 | } | 6026 | } |
| 6055 | 6027 | ||
| @@ -6076,7 +6048,8 @@ get_next_display_element (struct it *it) | |||
| 6076 | : STRINGP (it->string) ? IT_STRING_CHARPOS (*it) | 6048 | : STRINGP (it->string) ? IT_STRING_CHARPOS (*it) |
| 6077 | : IT_CHARPOS (*it)); | 6049 | : IT_CHARPOS (*it)); |
| 6078 | 6050 | ||
| 6079 | it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string); | 6051 | it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display, pos, |
| 6052 | it->string); | ||
| 6080 | } | 6053 | } |
| 6081 | } | 6054 | } |
| 6082 | #endif | 6055 | #endif |
| @@ -16558,15 +16531,19 @@ get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string) | |||
| 16558 | 16531 | ||
| 16559 | /* Get the next character. */ | 16532 | /* Get the next character. */ |
| 16560 | if (multibyte_p) | 16533 | if (multibyte_p) |
| 16561 | it.c = string_char_and_length (p, &it.len); | 16534 | it.c = it.char_to_display = string_char_and_length (p, &it.len); |
| 16562 | else | 16535 | else |
| 16563 | it.c = *p, it.len = 1; | 16536 | { |
| 16537 | it.c = it.char_to_display = *p, it.len = 1; | ||
| 16538 | if (! ASCII_CHAR_P (it.c)) | ||
| 16539 | it.char_to_display = BYTE8_TO_CHAR (it.c); | ||
| 16540 | } | ||
| 16564 | p += it.len; | 16541 | p += it.len; |
| 16565 | 16542 | ||
| 16566 | /* Get its face. */ | 16543 | /* Get its face. */ |
| 16567 | ilisp = make_number (p - arrow_string); | 16544 | ilisp = make_number (p - arrow_string); |
| 16568 | face = Fget_text_property (ilisp, Qface, overlay_arrow_string); | 16545 | face = Fget_text_property (ilisp, Qface, overlay_arrow_string); |
| 16569 | it.face_id = compute_char_face (f, it.c, face); | 16546 | it.face_id = compute_char_face (f, it.char_to_display, face); |
| 16570 | 16547 | ||
| 16571 | /* Compute its width, get its glyphs. */ | 16548 | /* Compute its width, get its glyphs. */ |
| 16572 | n_glyphs_before = it.glyph_row->used[TEXT_AREA]; | 16549 | n_glyphs_before = it.glyph_row->used[TEXT_AREA]; |
| @@ -16798,6 +16775,7 @@ append_space_for_newline (struct it *it, int default_face_p) | |||
| 16798 | append_space_for_newline has been called. */ | 16775 | append_space_for_newline has been called. */ |
| 16799 | enum display_element_type saved_what = it->what; | 16776 | enum display_element_type saved_what = it->what; |
| 16800 | int saved_c = it->c, saved_len = it->len; | 16777 | int saved_c = it->c, saved_len = it->len; |
| 16778 | int saved_char_to_display = it->char_to_display; | ||
| 16801 | int saved_x = it->current_x; | 16779 | int saved_x = it->current_x; |
| 16802 | int saved_face_id = it->face_id; | 16780 | int saved_face_id = it->face_id; |
| 16803 | struct text_pos saved_pos; | 16781 | struct text_pos saved_pos; |
| @@ -16810,7 +16788,7 @@ append_space_for_newline (struct it *it, int default_face_p) | |||
| 16810 | it->what = IT_CHARACTER; | 16788 | it->what = IT_CHARACTER; |
| 16811 | memset (&it->position, 0, sizeof it->position); | 16789 | memset (&it->position, 0, sizeof it->position); |
| 16812 | it->object = make_number (0); | 16790 | it->object = make_number (0); |
| 16813 | it->c = ' '; | 16791 | it->c = it->char_to_display = ' '; |
| 16814 | it->len = 1; | 16792 | it->len = 1; |
| 16815 | 16793 | ||
| 16816 | if (default_face_p) | 16794 | if (default_face_p) |
| @@ -16831,6 +16809,7 @@ append_space_for_newline (struct it *it, int default_face_p) | |||
| 16831 | it->face_id = saved_face_id; | 16809 | it->face_id = saved_face_id; |
| 16832 | it->len = saved_len; | 16810 | it->len = saved_len; |
| 16833 | it->c = saved_c; | 16811 | it->c = saved_c; |
| 16812 | it->char_to_display = saved_char_to_display; | ||
| 16834 | return 1; | 16813 | return 1; |
| 16835 | } | 16814 | } |
| 16836 | } | 16815 | } |
| @@ -16963,7 +16942,7 @@ extend_face_to_end_of_line (struct it *it) | |||
| 16963 | it->what = IT_CHARACTER; | 16942 | it->what = IT_CHARACTER; |
| 16964 | memset (&it->position, 0, sizeof it->position); | 16943 | memset (&it->position, 0, sizeof it->position); |
| 16965 | it->object = make_number (0); | 16944 | it->object = make_number (0); |
| 16966 | it->c = ' '; | 16945 | it->c = it->char_to_display = ' '; |
| 16967 | it->len = 1; | 16946 | it->len = 1; |
| 16968 | /* The last row's blank glyphs should get the default face, to | 16947 | /* The last row's blank glyphs should get the default face, to |
| 16969 | avoid painting the rest of the window with the region face, | 16948 | avoid painting the rest of the window with the region face, |
| @@ -20574,7 +20553,12 @@ get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph, | |||
| 20574 | 20553 | ||
| 20575 | if (face->font) | 20554 | if (face->font) |
| 20576 | { | 20555 | { |
| 20577 | unsigned code = face->font->driver->encode_char (face->font, glyph->u.ch); | 20556 | unsigned code; |
| 20557 | |||
| 20558 | if (CHAR_BYTE8_P (glyph->u.ch)) | ||
| 20559 | code = CHAR_TO_BYTE8 (glyph->u.ch); | ||
| 20560 | else | ||
| 20561 | code = face->font->driver->encode_char (face->font, glyph->u.ch); | ||
| 20578 | 20562 | ||
| 20579 | if (code != FONT_INVALID_CODE) | 20563 | if (code != FONT_INVALID_CODE) |
| 20580 | STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF)); | 20564 | STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF)); |
| @@ -20589,6 +20573,26 @@ get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph, | |||
| 20589 | } | 20573 | } |
| 20590 | 20574 | ||
| 20591 | 20575 | ||
| 20576 | /* Get glyph code of character C in FONT in the two-byte form CHAR2B. | ||
| 20577 | Retunr 1 if FONT has a glyph for C, otherwise return 0. */ | ||
| 20578 | |||
| 20579 | static INLINE int | ||
| 20580 | get_char_glyph_code (int c, struct font *font, XChar2b *char2b) | ||
| 20581 | { | ||
| 20582 | unsigned code; | ||
| 20583 | |||
| 20584 | if (CHAR_BYTE8_P (c)) | ||
| 20585 | code = CHAR_TO_BYTE8 (c); | ||
| 20586 | else | ||
| 20587 | code = font->driver->encode_char (font, c); | ||
| 20588 | |||
| 20589 | if (code == FONT_INVALID_CODE) | ||
| 20590 | return 0; | ||
| 20591 | STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF)); | ||
| 20592 | return 1; | ||
| 20593 | } | ||
| 20594 | |||
| 20595 | |||
| 20592 | /* Fill glyph string S with composition components specified by S->cmp. | 20596 | /* Fill glyph string S with composition components specified by S->cmp. |
| 20593 | 20597 | ||
| 20594 | BASE_FACE is the base face of the composition. | 20598 | BASE_FACE is the base face of the composition. |
| @@ -22131,10 +22135,14 @@ produce_stretch_glyph (struct it *it) | |||
| 22131 | { | 22135 | { |
| 22132 | int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT) | 22136 | int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT) |
| 22133 | - IT_BYTEPOS (*it)); | 22137 | - IT_BYTEPOS (*it)); |
| 22134 | it2.c = STRING_CHAR_AND_LENGTH (p, it2.len); | 22138 | it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len); |
| 22135 | } | 22139 | } |
| 22136 | else | 22140 | else |
| 22137 | it2.c = *p, it2.len = 1; | 22141 | { |
| 22142 | it2.c = it2.char_to_display = *p, it2.len = 1; | ||
| 22143 | if (! ASCII_CHAR_P (it2.c)) | ||
| 22144 | it2.char_to_display = BYTE8_TO_CHAR (it2.c); | ||
| 22145 | } | ||
| 22138 | 22146 | ||
| 22139 | it2.glyph_row = NULL; | 22147 | it2.glyph_row = NULL; |
| 22140 | it2.what = IT_CHARACTER; | 22148 | it2.what = IT_CHARACTER; |
| @@ -22304,49 +22312,12 @@ x_produce_glyphs (struct it *it) | |||
| 22304 | if (it->what == IT_CHARACTER) | 22312 | if (it->what == IT_CHARACTER) |
| 22305 | { | 22313 | { |
| 22306 | XChar2b char2b; | 22314 | XChar2b char2b; |
| 22307 | struct font *font; | ||
| 22308 | struct face *face = FACE_FROM_ID (it->f, it->face_id); | 22315 | struct face *face = FACE_FROM_ID (it->f, it->face_id); |
| 22309 | struct font_metrics *pcm; | 22316 | struct font *font = face->font; |
| 22310 | int font_not_found_p; | 22317 | int font_not_found_p = font == NULL; |
| 22318 | struct font_metrics *pcm = NULL; | ||
| 22311 | int boff; /* baseline offset */ | 22319 | int boff; /* baseline offset */ |
| 22312 | /* We may change it->multibyte_p upon unibyte<->multibyte | ||
| 22313 | conversion. So, save the current value now and restore it | ||
| 22314 | later. | ||
| 22315 | |||
| 22316 | Note: It seems that we don't have to record multibyte_p in | ||
| 22317 | struct glyph because the character code itself tells whether | ||
| 22318 | or not the character is multibyte. Thus, in the future, we | ||
| 22319 | must consider eliminating the field `multibyte_p' in the | ||
| 22320 | struct glyph. */ | ||
| 22321 | int saved_multibyte_p = it->multibyte_p; | ||
| 22322 | |||
| 22323 | /* Maybe translate single-byte characters to multibyte, or the | ||
| 22324 | other way. */ | ||
| 22325 | it->char_to_display = it->c; | ||
| 22326 | if (!ASCII_BYTE_P (it->c) | ||
| 22327 | && ! it->multibyte_p) | ||
| 22328 | { | ||
| 22329 | if (SINGLE_BYTE_CHAR_P (it->c) | ||
| 22330 | && unibyte_display_via_language_environment) | ||
| 22331 | { | ||
| 22332 | struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte); | ||
| 22333 | |||
| 22334 | /* get_next_display_element assures that this decoding | ||
| 22335 | never fails. */ | ||
| 22336 | it->char_to_display = DECODE_CHAR (unibyte, it->c); | ||
| 22337 | it->multibyte_p = 1; | ||
| 22338 | it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display, | ||
| 22339 | -1, Qnil); | ||
| 22340 | face = FACE_FROM_ID (it->f, it->face_id); | ||
| 22341 | } | ||
| 22342 | } | ||
| 22343 | |||
| 22344 | /* Get font to use. Encode IT->char_to_display. */ | ||
| 22345 | get_char_face_and_encoding (it->f, it->char_to_display, it->face_id, | ||
| 22346 | &char2b, it->multibyte_p, 0); | ||
| 22347 | font = face->font; | ||
| 22348 | 22320 | ||
| 22349 | font_not_found_p = font == NULL; | ||
| 22350 | if (font_not_found_p) | 22321 | if (font_not_found_p) |
| 22351 | { | 22322 | { |
| 22352 | /* When no suitable font found, display an empty box based | 22323 | /* When no suitable font found, display an empty box based |
| @@ -22366,16 +22337,12 @@ x_produce_glyphs (struct it *it) | |||
| 22366 | boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; | 22337 | boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; |
| 22367 | } | 22338 | } |
| 22368 | 22339 | ||
| 22369 | if (it->char_to_display >= ' ' | 22340 | if (it->char_to_display != '\n' && it->char_to_display != '\t') |
| 22370 | && (!it->multibyte_p || it->char_to_display < 128)) | ||
| 22371 | { | 22341 | { |
| 22372 | /* Either unibyte or ASCII. */ | ||
| 22373 | int stretched_p; | 22342 | int stretched_p; |
| 22374 | 22343 | ||
| 22375 | it->nglyphs = 1; | 22344 | it->nglyphs = 1; |
| 22376 | 22345 | ||
| 22377 | pcm = get_per_char_metric (it->f, font, &char2b); | ||
| 22378 | |||
| 22379 | if (it->override_ascent >= 0) | 22346 | if (it->override_ascent >= 0) |
| 22380 | { | 22347 | { |
| 22381 | it->ascent = it->override_ascent; | 22348 | it->ascent = it->override_ascent; |
| @@ -22388,6 +22355,15 @@ x_produce_glyphs (struct it *it) | |||
| 22388 | it->descent = FONT_DESCENT (font) - boff; | 22355 | it->descent = FONT_DESCENT (font) - boff; |
| 22389 | } | 22356 | } |
| 22390 | 22357 | ||
| 22358 | if (! font_not_found_p | ||
| 22359 | && get_char_glyph_code (it->char_to_display, font, &char2b)) | ||
| 22360 | { | ||
| 22361 | pcm = get_per_char_metric (it->f, font, &char2b); | ||
| 22362 | if (pcm->width == 0 | ||
| 22363 | && pcm->rbearing == 0 && pcm->lbearing == 0) | ||
| 22364 | pcm = NULL; | ||
| 22365 | } | ||
| 22366 | |||
| 22391 | if (pcm) | 22367 | if (pcm) |
| 22392 | { | 22368 | { |
| 22393 | it->phys_ascent = pcm->ascent + boff; | 22369 | it->phys_ascent = pcm->ascent + boff; |
| @@ -22399,7 +22375,7 @@ x_produce_glyphs (struct it *it) | |||
| 22399 | it->glyph_not_available_p = 1; | 22375 | it->glyph_not_available_p = 1; |
| 22400 | it->phys_ascent = it->ascent; | 22376 | it->phys_ascent = it->ascent; |
| 22401 | it->phys_descent = it->descent; | 22377 | it->phys_descent = it->descent; |
| 22402 | it->pixel_width = FONT_WIDTH (font); | 22378 | it->pixel_width = font->space_width; |
| 22403 | } | 22379 | } |
| 22404 | 22380 | ||
| 22405 | if (it->constrain_row_ascent_descent_p) | 22381 | if (it->constrain_row_ascent_descent_p) |
| @@ -22573,7 +22549,7 @@ x_produce_glyphs (struct it *it) | |||
| 22573 | } | 22549 | } |
| 22574 | } | 22550 | } |
| 22575 | } | 22551 | } |
| 22576 | else if (it->char_to_display == '\t') | 22552 | else /* i.e. (it->char_to_display == '\t') */ |
| 22577 | { | 22553 | { |
| 22578 | if (font->space_width > 0) | 22554 | if (font->space_width > 0) |
| 22579 | { | 22555 | { |
| @@ -22604,85 +22580,6 @@ x_produce_glyphs (struct it *it) | |||
| 22604 | it->nglyphs = 1; | 22580 | it->nglyphs = 1; |
| 22605 | } | 22581 | } |
| 22606 | } | 22582 | } |
| 22607 | else | ||
| 22608 | { | ||
| 22609 | /* A multi-byte character. Assume that the display width of the | ||
| 22610 | character is the width of the character multiplied by the | ||
| 22611 | width of the font. */ | ||
| 22612 | |||
| 22613 | /* If we found a font, this font should give us the right | ||
| 22614 | metrics. If we didn't find a font, use the frame's | ||
| 22615 | default font and calculate the width of the character by | ||
| 22616 | multiplying the width of font by the width of the | ||
| 22617 | character. */ | ||
| 22618 | |||
| 22619 | pcm = get_per_char_metric (it->f, font, &char2b); | ||
| 22620 | |||
| 22621 | if (font_not_found_p || !pcm) | ||
| 22622 | { | ||
| 22623 | int char_width = CHAR_WIDTH (it->char_to_display); | ||
| 22624 | |||
| 22625 | if (char_width == 0) | ||
| 22626 | /* This is a non spacing character. But, as we are | ||
| 22627 | going to display an empty box, the box must occupy | ||
| 22628 | at least one column. */ | ||
| 22629 | char_width = 1; | ||
| 22630 | it->glyph_not_available_p = 1; | ||
| 22631 | it->pixel_width = font->space_width * char_width; | ||
| 22632 | it->phys_ascent = FONT_BASE (font) + boff; | ||
| 22633 | it->phys_descent = FONT_DESCENT (font) - boff; | ||
| 22634 | } | ||
| 22635 | else | ||
| 22636 | { | ||
| 22637 | it->pixel_width = pcm->width; | ||
| 22638 | it->phys_ascent = pcm->ascent + boff; | ||
| 22639 | it->phys_descent = pcm->descent - boff; | ||
| 22640 | if (it->glyph_row | ||
| 22641 | && (pcm->lbearing < 0 | ||
| 22642 | || pcm->rbearing > pcm->width)) | ||
| 22643 | it->glyph_row->contains_overlapping_glyphs_p = 1; | ||
| 22644 | } | ||
| 22645 | it->nglyphs = 1; | ||
| 22646 | it->ascent = FONT_BASE (font) + boff; | ||
| 22647 | it->descent = FONT_DESCENT (font) - boff; | ||
| 22648 | if (face->box != FACE_NO_BOX) | ||
| 22649 | { | ||
| 22650 | int thick = face->box_line_width; | ||
| 22651 | |||
| 22652 | if (thick > 0) | ||
| 22653 | { | ||
| 22654 | it->ascent += thick; | ||
| 22655 | it->descent += thick; | ||
| 22656 | } | ||
| 22657 | else | ||
| 22658 | thick = - thick; | ||
| 22659 | |||
| 22660 | if (it->start_of_box_run_p) | ||
| 22661 | it->pixel_width += thick; | ||
| 22662 | if (it->end_of_box_run_p) | ||
| 22663 | it->pixel_width += thick; | ||
| 22664 | } | ||
| 22665 | |||
| 22666 | /* If face has an overline, add the height of the overline | ||
| 22667 | (1 pixel) and a 1 pixel margin to the character height. */ | ||
| 22668 | if (face->overline_p) | ||
| 22669 | it->ascent += overline_margin; | ||
| 22670 | |||
| 22671 | take_vertical_position_into_account (it); | ||
| 22672 | |||
| 22673 | if (it->ascent < 0) | ||
| 22674 | it->ascent = 0; | ||
| 22675 | if (it->descent < 0) | ||
| 22676 | it->descent = 0; | ||
| 22677 | |||
| 22678 | if (it->glyph_row) | ||
| 22679 | append_glyph (it); | ||
| 22680 | if (it->pixel_width == 0) | ||
| 22681 | /* We assure that all visible glyphs have at least 1-pixel | ||
| 22682 | width. */ | ||
| 22683 | it->pixel_width = 1; | ||
| 22684 | } | ||
| 22685 | it->multibyte_p = saved_multibyte_p; | ||
| 22686 | } | 22583 | } |
| 22687 | else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0) | 22584 | else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0) |
| 22688 | { | 22585 | { |
| @@ -22778,7 +22675,7 @@ x_produce_glyphs (struct it *it) | |||
| 22778 | } | 22675 | } |
| 22779 | else | 22676 | else |
| 22780 | { | 22677 | { |
| 22781 | width = FONT_WIDTH (font); | 22678 | width = font->space_width; |
| 22782 | ascent = FONT_BASE (font); | 22679 | ascent = FONT_BASE (font); |
| 22783 | descent = FONT_DESCENT (font); | 22680 | descent = FONT_DESCENT (font); |
| 22784 | lbearing = 0; | 22681 | lbearing = 0; |
diff --git a/src/xselect.c b/src/xselect.c index 21684c83088..7479f245a77 100644 --- a/src/xselect.c +++ b/src/xselect.c | |||
| @@ -83,8 +83,6 @@ static void lisp_data_to_selection_data (Display *, Lisp_Object, | |||
| 83 | unsigned char **, Atom *, | 83 | unsigned char **, Atom *, |
| 84 | unsigned *, int *, int *); | 84 | unsigned *, int *, int *); |
| 85 | static Lisp_Object clean_local_selection_data (Lisp_Object); | 85 | static Lisp_Object clean_local_selection_data (Lisp_Object); |
| 86 | static void initialize_cut_buffers (Display *, Window); | ||
| 87 | |||
| 88 | 86 | ||
| 89 | /* Printing traces to stderr. */ | 87 | /* Printing traces to stderr. */ |
| 90 | 88 | ||
| @@ -105,8 +103,6 @@ static void initialize_cut_buffers (Display *, Window); | |||
| 105 | #endif | 103 | #endif |
| 106 | 104 | ||
| 107 | 105 | ||
| 108 | #define CUT_BUFFER_SUPPORT | ||
| 109 | |||
| 110 | Lisp_Object QSECONDARY, QSTRING, QINTEGER, QCLIPBOARD, QTIMESTAMP, | 106 | Lisp_Object QSECONDARY, QSTRING, QINTEGER, QCLIPBOARD, QTIMESTAMP, |
| 111 | QTEXT, QDELETE, QMULTIPLE, QINCR, QEMACS_TMP, QTARGETS, QATOM, QNULL, | 107 | QTEXT, QDELETE, QMULTIPLE, QINCR, QEMACS_TMP, QTARGETS, QATOM, QNULL, |
| 112 | QATOM_PAIR; | 108 | QATOM_PAIR; |
| @@ -116,11 +112,6 @@ Lisp_Object QUTF8_STRING; /* This is a type of selection. */ | |||
| 116 | 112 | ||
| 117 | Lisp_Object Qcompound_text_with_extensions; | 113 | Lisp_Object Qcompound_text_with_extensions; |
| 118 | 114 | ||
| 119 | #ifdef CUT_BUFFER_SUPPORT | ||
| 120 | Lisp_Object QCUT_BUFFER0, QCUT_BUFFER1, QCUT_BUFFER2, QCUT_BUFFER3, | ||
| 121 | QCUT_BUFFER4, QCUT_BUFFER5, QCUT_BUFFER6, QCUT_BUFFER7; | ||
| 122 | #endif | ||
| 123 | |||
| 124 | static Lisp_Object Vx_lost_selection_functions; | 115 | static Lisp_Object Vx_lost_selection_functions; |
| 125 | static Lisp_Object Vx_sent_selection_functions; | 116 | static Lisp_Object Vx_sent_selection_functions; |
| 126 | static Lisp_Object Qforeign_selection; | 117 | static Lisp_Object Qforeign_selection; |
| @@ -270,16 +261,6 @@ symbol_to_x_atom (struct x_display_info *dpyinfo, Display *display, Lisp_Object | |||
| 270 | if (EQ (sym, QEMACS_TMP)) return dpyinfo->Xatom_EMACS_TMP; | 261 | if (EQ (sym, QEMACS_TMP)) return dpyinfo->Xatom_EMACS_TMP; |
| 271 | if (EQ (sym, QTARGETS)) return dpyinfo->Xatom_TARGETS; | 262 | if (EQ (sym, QTARGETS)) return dpyinfo->Xatom_TARGETS; |
| 272 | if (EQ (sym, QNULL)) return dpyinfo->Xatom_NULL; | 263 | if (EQ (sym, QNULL)) return dpyinfo->Xatom_NULL; |
| 273 | #ifdef CUT_BUFFER_SUPPORT | ||
| 274 | if (EQ (sym, QCUT_BUFFER0)) return XA_CUT_BUFFER0; | ||
| 275 | if (EQ (sym, QCUT_BUFFER1)) return XA_CUT_BUFFER1; | ||
| 276 | if (EQ (sym, QCUT_BUFFER2)) return XA_CUT_BUFFER2; | ||
| 277 | if (EQ (sym, QCUT_BUFFER3)) return XA_CUT_BUFFER3; | ||
| 278 | if (EQ (sym, QCUT_BUFFER4)) return XA_CUT_BUFFER4; | ||
| 279 | if (EQ (sym, QCUT_BUFFER5)) return XA_CUT_BUFFER5; | ||
| 280 | if (EQ (sym, QCUT_BUFFER6)) return XA_CUT_BUFFER6; | ||
| 281 | if (EQ (sym, QCUT_BUFFER7)) return XA_CUT_BUFFER7; | ||
| 282 | #endif | ||
| 283 | if (!SYMBOLP (sym)) abort (); | 264 | if (!SYMBOLP (sym)) abort (); |
| 284 | 265 | ||
| 285 | TRACE1 (" XInternAtom %s", (char *) SDATA (SYMBOL_NAME (sym))); | 266 | TRACE1 (" XInternAtom %s", (char *) SDATA (SYMBOL_NAME (sym))); |
| @@ -315,24 +296,6 @@ x_atom_to_symbol (Display *dpy, Atom atom) | |||
| 315 | return QINTEGER; | 296 | return QINTEGER; |
| 316 | case XA_ATOM: | 297 | case XA_ATOM: |
| 317 | return QATOM; | 298 | return QATOM; |
| 318 | #ifdef CUT_BUFFER_SUPPORT | ||
| 319 | case XA_CUT_BUFFER0: | ||
| 320 | return QCUT_BUFFER0; | ||
| 321 | case XA_CUT_BUFFER1: | ||
| 322 | return QCUT_BUFFER1; | ||
| 323 | case XA_CUT_BUFFER2: | ||
| 324 | return QCUT_BUFFER2; | ||
| 325 | case XA_CUT_BUFFER3: | ||
| 326 | return QCUT_BUFFER3; | ||
| 327 | case XA_CUT_BUFFER4: | ||
| 328 | return QCUT_BUFFER4; | ||
| 329 | case XA_CUT_BUFFER5: | ||
| 330 | return QCUT_BUFFER5; | ||
| 331 | case XA_CUT_BUFFER6: | ||
| 332 | return QCUT_BUFFER6; | ||
| 333 | case XA_CUT_BUFFER7: | ||
| 334 | return QCUT_BUFFER7; | ||
| 335 | #endif | ||
| 336 | } | 299 | } |
| 337 | 300 | ||
| 338 | dpyinfo = x_display_info_for_display (dpy); | 301 | dpyinfo = x_display_info_for_display (dpy); |
| @@ -2258,195 +2221,6 @@ and t is the same as `SECONDARY'. */) | |||
| 2258 | } | 2221 | } |
| 2259 | 2222 | ||
| 2260 | 2223 | ||
| 2261 | #ifdef CUT_BUFFER_SUPPORT | ||
| 2262 | |||
| 2263 | /* Ensure that all 8 cut buffers exist. ICCCM says we gotta... */ | ||
| 2264 | static void | ||
| 2265 | initialize_cut_buffers (Display *display, Window window) | ||
| 2266 | { | ||
| 2267 | unsigned char *data = (unsigned char *) ""; | ||
| 2268 | BLOCK_INPUT; | ||
| 2269 | #define FROB(atom) XChangeProperty (display, window, atom, XA_STRING, 8, \ | ||
| 2270 | PropModeAppend, data, 0) | ||
| 2271 | FROB (XA_CUT_BUFFER0); | ||
| 2272 | FROB (XA_CUT_BUFFER1); | ||
| 2273 | FROB (XA_CUT_BUFFER2); | ||
| 2274 | FROB (XA_CUT_BUFFER3); | ||
| 2275 | FROB (XA_CUT_BUFFER4); | ||
| 2276 | FROB (XA_CUT_BUFFER5); | ||
| 2277 | FROB (XA_CUT_BUFFER6); | ||
| 2278 | FROB (XA_CUT_BUFFER7); | ||
| 2279 | #undef FROB | ||
| 2280 | UNBLOCK_INPUT; | ||
| 2281 | } | ||
| 2282 | |||
| 2283 | |||
| 2284 | #define CHECK_CUT_BUFFER(symbol) \ | ||
| 2285 | do { CHECK_SYMBOL ((symbol)); \ | ||
| 2286 | if (!EQ((symbol), QCUT_BUFFER0) && !EQ((symbol), QCUT_BUFFER1) \ | ||
| 2287 | && !EQ((symbol), QCUT_BUFFER2) && !EQ((symbol), QCUT_BUFFER3) \ | ||
| 2288 | && !EQ((symbol), QCUT_BUFFER4) && !EQ((symbol), QCUT_BUFFER5) \ | ||
| 2289 | && !EQ((symbol), QCUT_BUFFER6) && !EQ((symbol), QCUT_BUFFER7)) \ | ||
| 2290 | signal_error ("Doesn't name a cut buffer", (symbol)); \ | ||
| 2291 | } while (0) | ||
| 2292 | |||
| 2293 | DEFUN ("x-get-cut-buffer-internal", Fx_get_cut_buffer_internal, | ||
| 2294 | Sx_get_cut_buffer_internal, 1, 1, 0, | ||
| 2295 | doc: /* Returns the value of the named cut buffer (typically CUT_BUFFER0). */) | ||
| 2296 | (Lisp_Object buffer) | ||
| 2297 | { | ||
| 2298 | Window window; | ||
| 2299 | Atom buffer_atom; | ||
| 2300 | unsigned char *data = NULL; | ||
| 2301 | int bytes; | ||
| 2302 | Atom type; | ||
| 2303 | int format; | ||
| 2304 | unsigned long size; | ||
| 2305 | Lisp_Object ret; | ||
| 2306 | Display *display; | ||
| 2307 | struct x_display_info *dpyinfo; | ||
| 2308 | struct frame *sf = SELECTED_FRAME (); | ||
| 2309 | |||
| 2310 | check_x (); | ||
| 2311 | |||
| 2312 | if (! FRAME_X_P (sf)) | ||
| 2313 | return Qnil; | ||
| 2314 | |||
| 2315 | display = FRAME_X_DISPLAY (sf); | ||
| 2316 | dpyinfo = FRAME_X_DISPLAY_INFO (sf); | ||
| 2317 | window = RootWindow (display, 0); /* Cut buffers are on screen 0 */ | ||
| 2318 | CHECK_CUT_BUFFER (buffer); | ||
| 2319 | buffer_atom = symbol_to_x_atom (dpyinfo, display, buffer); | ||
| 2320 | |||
| 2321 | x_get_window_property (display, window, buffer_atom, &data, &bytes, | ||
| 2322 | &type, &format, &size, 0); | ||
| 2323 | |||
| 2324 | if (!data || !format) | ||
| 2325 | { | ||
| 2326 | xfree (data); | ||
| 2327 | return Qnil; | ||
| 2328 | } | ||
| 2329 | |||
| 2330 | if (format != 8 || type != XA_STRING) | ||
| 2331 | signal_error ("Cut buffer doesn't contain 8-bit data", | ||
| 2332 | list2 (x_atom_to_symbol (display, type), | ||
| 2333 | make_number (format))); | ||
| 2334 | |||
| 2335 | ret = (bytes ? make_unibyte_string ((char *) data, bytes) : Qnil); | ||
| 2336 | /* Use xfree, not XFree, because x_get_window_property | ||
| 2337 | calls xmalloc itself. */ | ||
| 2338 | xfree (data); | ||
| 2339 | return ret; | ||
| 2340 | } | ||
| 2341 | |||
| 2342 | |||
| 2343 | DEFUN ("x-store-cut-buffer-internal", Fx_store_cut_buffer_internal, | ||
| 2344 | Sx_store_cut_buffer_internal, 2, 2, 0, | ||
| 2345 | doc: /* Sets the value of the named cut buffer (typically CUT_BUFFER0). */) | ||
| 2346 | (Lisp_Object buffer, Lisp_Object string) | ||
| 2347 | { | ||
| 2348 | Window window; | ||
| 2349 | Atom buffer_atom; | ||
| 2350 | unsigned char *data; | ||
| 2351 | int bytes; | ||
| 2352 | int bytes_remaining; | ||
| 2353 | int max_bytes; | ||
| 2354 | Display *display; | ||
| 2355 | struct frame *sf = SELECTED_FRAME (); | ||
| 2356 | |||
| 2357 | check_x (); | ||
| 2358 | |||
| 2359 | if (! FRAME_X_P (sf)) | ||
| 2360 | return Qnil; | ||
| 2361 | |||
| 2362 | display = FRAME_X_DISPLAY (sf); | ||
| 2363 | window = RootWindow (display, 0); /* Cut buffers are on screen 0 */ | ||
| 2364 | |||
| 2365 | max_bytes = SELECTION_QUANTUM (display); | ||
| 2366 | if (max_bytes > MAX_SELECTION_QUANTUM) | ||
| 2367 | max_bytes = MAX_SELECTION_QUANTUM; | ||
| 2368 | |||
| 2369 | CHECK_CUT_BUFFER (buffer); | ||
| 2370 | CHECK_STRING (string); | ||
| 2371 | buffer_atom = symbol_to_x_atom (FRAME_X_DISPLAY_INFO (sf), | ||
| 2372 | display, buffer); | ||
| 2373 | data = (unsigned char *) SDATA (string); | ||
| 2374 | bytes = SBYTES (string); | ||
| 2375 | bytes_remaining = bytes; | ||
| 2376 | |||
| 2377 | if (! FRAME_X_DISPLAY_INFO (sf)->cut_buffers_initialized) | ||
| 2378 | { | ||
| 2379 | initialize_cut_buffers (display, window); | ||
| 2380 | FRAME_X_DISPLAY_INFO (sf)->cut_buffers_initialized = 1; | ||
| 2381 | } | ||
| 2382 | |||
| 2383 | BLOCK_INPUT; | ||
| 2384 | |||
| 2385 | /* Don't mess up with an empty value. */ | ||
| 2386 | if (!bytes_remaining) | ||
| 2387 | XChangeProperty (display, window, buffer_atom, XA_STRING, 8, | ||
| 2388 | PropModeReplace, data, 0); | ||
| 2389 | |||
| 2390 | while (bytes_remaining) | ||
| 2391 | { | ||
| 2392 | int chunk = (bytes_remaining < max_bytes | ||
| 2393 | ? bytes_remaining : max_bytes); | ||
| 2394 | XChangeProperty (display, window, buffer_atom, XA_STRING, 8, | ||
| 2395 | (bytes_remaining == bytes | ||
| 2396 | ? PropModeReplace | ||
| 2397 | : PropModeAppend), | ||
| 2398 | data, chunk); | ||
| 2399 | data += chunk; | ||
| 2400 | bytes_remaining -= chunk; | ||
| 2401 | } | ||
| 2402 | UNBLOCK_INPUT; | ||
| 2403 | return string; | ||
| 2404 | } | ||
| 2405 | |||
| 2406 | |||
| 2407 | DEFUN ("x-rotate-cut-buffers-internal", Fx_rotate_cut_buffers_internal, | ||
| 2408 | Sx_rotate_cut_buffers_internal, 1, 1, 0, | ||
| 2409 | doc: /* Rotate the values of the cut buffers by N steps. | ||
| 2410 | Positive N means shift the values forward, negative means backward. */) | ||
| 2411 | (Lisp_Object n) | ||
| 2412 | { | ||
| 2413 | Window window; | ||
| 2414 | Atom props[8]; | ||
| 2415 | Display *display; | ||
| 2416 | struct frame *sf = SELECTED_FRAME (); | ||
| 2417 | |||
| 2418 | check_x (); | ||
| 2419 | |||
| 2420 | if (! FRAME_X_P (sf)) | ||
| 2421 | return Qnil; | ||
| 2422 | |||
| 2423 | display = FRAME_X_DISPLAY (sf); | ||
| 2424 | window = RootWindow (display, 0); /* Cut buffers are on screen 0 */ | ||
| 2425 | CHECK_NUMBER (n); | ||
| 2426 | if (XINT (n) == 0) | ||
| 2427 | return n; | ||
| 2428 | if (! FRAME_X_DISPLAY_INFO (sf)->cut_buffers_initialized) | ||
| 2429 | { | ||
| 2430 | initialize_cut_buffers (display, window); | ||
| 2431 | FRAME_X_DISPLAY_INFO (sf)->cut_buffers_initialized = 1; | ||
| 2432 | } | ||
| 2433 | |||
| 2434 | props[0] = XA_CUT_BUFFER0; | ||
| 2435 | props[1] = XA_CUT_BUFFER1; | ||
| 2436 | props[2] = XA_CUT_BUFFER2; | ||
| 2437 | props[3] = XA_CUT_BUFFER3; | ||
| 2438 | props[4] = XA_CUT_BUFFER4; | ||
| 2439 | props[5] = XA_CUT_BUFFER5; | ||
| 2440 | props[6] = XA_CUT_BUFFER6; | ||
| 2441 | props[7] = XA_CUT_BUFFER7; | ||
| 2442 | BLOCK_INPUT; | ||
| 2443 | XRotateWindowProperties (display, window, props, 8, XINT (n)); | ||
| 2444 | UNBLOCK_INPUT; | ||
| 2445 | return n; | ||
| 2446 | } | ||
| 2447 | |||
| 2448 | #endif | ||
| 2449 | |||
| 2450 | /*********************************************************************** | 2224 | /*********************************************************************** |
| 2451 | Drag and drop support | 2225 | Drag and drop support |
| 2452 | ***********************************************************************/ | 2226 | ***********************************************************************/ |
| @@ -2850,12 +2624,6 @@ syms_of_xselect (void) | |||
| 2850 | defsubr (&Sx_selection_owner_p); | 2624 | defsubr (&Sx_selection_owner_p); |
| 2851 | defsubr (&Sx_selection_exists_p); | 2625 | defsubr (&Sx_selection_exists_p); |
| 2852 | 2626 | ||
| 2853 | #ifdef CUT_BUFFER_SUPPORT | ||
| 2854 | defsubr (&Sx_get_cut_buffer_internal); | ||
| 2855 | defsubr (&Sx_store_cut_buffer_internal); | ||
| 2856 | defsubr (&Sx_rotate_cut_buffers_internal); | ||
| 2857 | #endif | ||
| 2858 | |||
| 2859 | defsubr (&Sx_get_atom_name); | 2627 | defsubr (&Sx_get_atom_name); |
| 2860 | defsubr (&Sx_send_client_message); | 2628 | defsubr (&Sx_send_client_message); |
| 2861 | defsubr (&Sx_register_dnd_atom); | 2629 | defsubr (&Sx_register_dnd_atom); |
| @@ -2937,17 +2705,6 @@ A value of 0 means wait as long as necessary. This is initialized from the | |||
| 2937 | Qcompound_text_with_extensions = intern_c_string ("compound-text-with-extensions"); | 2705 | Qcompound_text_with_extensions = intern_c_string ("compound-text-with-extensions"); |
| 2938 | staticpro (&Qcompound_text_with_extensions); | 2706 | staticpro (&Qcompound_text_with_extensions); |
| 2939 | 2707 | ||
| 2940 | #ifdef CUT_BUFFER_SUPPORT | ||
| 2941 | QCUT_BUFFER0 = intern_c_string ("CUT_BUFFER0"); staticpro (&QCUT_BUFFER0); | ||
| 2942 | QCUT_BUFFER1 = intern_c_string ("CUT_BUFFER1"); staticpro (&QCUT_BUFFER1); | ||
| 2943 | QCUT_BUFFER2 = intern_c_string ("CUT_BUFFER2"); staticpro (&QCUT_BUFFER2); | ||
| 2944 | QCUT_BUFFER3 = intern_c_string ("CUT_BUFFER3"); staticpro (&QCUT_BUFFER3); | ||
| 2945 | QCUT_BUFFER4 = intern_c_string ("CUT_BUFFER4"); staticpro (&QCUT_BUFFER4); | ||
| 2946 | QCUT_BUFFER5 = intern_c_string ("CUT_BUFFER5"); staticpro (&QCUT_BUFFER5); | ||
| 2947 | QCUT_BUFFER6 = intern_c_string ("CUT_BUFFER6"); staticpro (&QCUT_BUFFER6); | ||
| 2948 | QCUT_BUFFER7 = intern_c_string ("CUT_BUFFER7"); staticpro (&QCUT_BUFFER7); | ||
| 2949 | #endif | ||
| 2950 | |||
| 2951 | Qforeign_selection = intern_c_string ("foreign-selection"); | 2708 | Qforeign_selection = intern_c_string ("foreign-selection"); |
| 2952 | staticpro (&Qforeign_selection); | 2709 | staticpro (&Qforeign_selection); |
| 2953 | } | 2710 | } |
diff --git a/src/xterm.c b/src/xterm.c index a07279f987e..67cc250a1b2 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -10150,8 +10150,6 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 10150 | dpyinfo->Xatom_net_wm_name | 10150 | dpyinfo->Xatom_net_wm_name |
| 10151 | = XInternAtom (dpyinfo->display, "_NET_WM_NAME", False); | 10151 | = XInternAtom (dpyinfo->display, "_NET_WM_NAME", False); |
| 10152 | 10152 | ||
| 10153 | dpyinfo->cut_buffers_initialized = 0; | ||
| 10154 | |||
| 10155 | dpyinfo->x_dnd_atoms_size = 8; | 10153 | dpyinfo->x_dnd_atoms_size = 8; |
| 10156 | dpyinfo->x_dnd_atoms_length = 0; | 10154 | dpyinfo->x_dnd_atoms_length = 0; |
| 10157 | dpyinfo->x_dnd_atoms = xmalloc (sizeof (*dpyinfo->x_dnd_atoms) | 10155 | dpyinfo->x_dnd_atoms = xmalloc (sizeof (*dpyinfo->x_dnd_atoms) |
diff --git a/src/xterm.h b/src/xterm.h index 972bfb50dc3..d884945f985 100644 --- a/src/xterm.h +++ b/src/xterm.h | |||
| @@ -299,8 +299,6 @@ struct x_display_info | |||
| 299 | /* Atom used in XEmbed client messages. */ | 299 | /* Atom used in XEmbed client messages. */ |
| 300 | Atom Xatom_XEMBED; | 300 | Atom Xatom_XEMBED; |
| 301 | 301 | ||
| 302 | int cut_buffers_initialized; /* Whether we're sure they all exist */ | ||
| 303 | |||
| 304 | /* The frame (if any) which has the X window that has keyboard focus. | 302 | /* The frame (if any) which has the X window that has keyboard focus. |
| 305 | Zero if none. This is examined by Ffocus_frame in xfns.c. Note | 303 | Zero if none. This is examined by Ffocus_frame in xfns.c. Note |
| 306 | that a mere EnterNotify event can set this; if you need to know the | 304 | that a mere EnterNotify event can set this; if you need to know the |