diff options
| author | Andrea Corallo | 2020-08-23 11:52:18 +0200 |
|---|---|---|
| committer | Andrea Corallo | 2020-08-23 11:52:18 +0200 |
| commit | fafc9c21175ee50df84114a09e9f43f02c960b85 (patch) | |
| tree | bd07feaed951d7bd49ed53d65bb2e6082a6c1196 /src | |
| parent | c818c29771d3cb51875643b2f6c894073e429dd2 (diff) | |
| parent | 4e97019a77731d634e6b059954c8fef792c11fa8 (diff) | |
| download | emacs-fafc9c21175ee50df84114a09e9f43f02c960b85.tar.gz emacs-fafc9c21175ee50df84114a09e9f43f02c960b85.zip | |
Merge remote-tracking branch 'savannah/master' into HEAD
Diffstat (limited to 'src')
| -rw-r--r-- | src/callproc.c | 6 | ||||
| -rw-r--r-- | src/ccl.c | 2 | ||||
| -rw-r--r-- | src/editfns.c | 3 | ||||
| -rw-r--r-- | src/image.c | 2 | ||||
| -rw-r--r-- | src/minibuf.c | 2 | ||||
| -rw-r--r-- | src/nsfns.m | 139 | ||||
| -rw-r--r-- | src/nsterm.h | 6 | ||||
| -rw-r--r-- | src/nsterm.m | 25 | ||||
| -rw-r--r-- | src/process.c | 5 | ||||
| -rw-r--r-- | src/thread.c | 8 | ||||
| -rw-r--r-- | src/xdisp.c | 189 | ||||
| -rw-r--r-- | src/xgselect.c | 42 | ||||
| -rw-r--r-- | src/xgselect.h | 2 |
13 files changed, 308 insertions, 123 deletions
diff --git a/src/callproc.c b/src/callproc.c index 65c858393a9..e3346e2eabb 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -231,6 +231,9 @@ DESTINATION can also have the form (REAL-BUFFER STDERR-FILE); in that case, | |||
| 231 | Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted. | 231 | Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted. |
| 232 | Remaining arguments ARGS are strings passed as command arguments to PROGRAM. | 232 | Remaining arguments ARGS are strings passed as command arguments to PROGRAM. |
| 233 | 233 | ||
| 234 | If PROGRAM is not an absolute file name, `call-process' will look for | ||
| 235 | PROGRAM in `exec-path' (which is a list of directories). | ||
| 236 | |||
| 234 | If executable PROGRAM can't be found as an executable, `call-process' | 237 | If executable PROGRAM can't be found as an executable, `call-process' |
| 235 | signals a Lisp error. `call-process' reports errors in execution of | 238 | signals a Lisp error. `call-process' reports errors in execution of |
| 236 | the program only through its return and output. | 239 | the program only through its return and output. |
| @@ -1060,6 +1063,9 @@ Sixth arg DISPLAY non-nil means redisplay buffer as output is inserted. | |||
| 1060 | Remaining arguments ARGS are passed to PROGRAM at startup as command-line | 1063 | Remaining arguments ARGS are passed to PROGRAM at startup as command-line |
| 1061 | arguments. | 1064 | arguments. |
| 1062 | 1065 | ||
| 1066 | If PROGRAM is not an absolute file name, `call-process-region' will | ||
| 1067 | look for PROGRAM in `exec-path' (which is a list of directories). | ||
| 1068 | |||
| 1063 | If BUFFER is 0, `call-process-region' returns immediately with value nil. | 1069 | If BUFFER is 0, `call-process-region' returns immediately with value nil. |
| 1064 | Otherwise it waits for PROGRAM to terminate | 1070 | Otherwise it waits for PROGRAM to terminate |
| 1065 | and returns a numeric exit status or a signal description string. | 1071 | and returns a numeric exit status or a signal description string. |
| @@ -1374,7 +1374,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size | |||
| 1374 | if (! (IN_INT_RANGE (eop) && CHARACTERP (opl))) | 1374 | if (! (IN_INT_RANGE (eop) && CHARACTERP (opl))) |
| 1375 | CCL_INVALID_CMD; | 1375 | CCL_INVALID_CMD; |
| 1376 | reg[RRR] = charset_unicode; | 1376 | reg[RRR] = charset_unicode; |
| 1377 | reg[rrr] = eop; | 1377 | reg[rrr] = XFIXNUM (opl); |
| 1378 | reg[7] = 1; /* r7 true for success */ | 1378 | reg[7] = 1; /* r7 true for success */ |
| 1379 | } | 1379 | } |
| 1380 | else | 1380 | else |
diff --git a/src/editfns.c b/src/editfns.c index cb09ea8a31a..949f3825a3c 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -707,7 +707,8 @@ If the scan reaches the end of the buffer, return that position. | |||
| 707 | 707 | ||
| 708 | This function ignores text display directionality; it returns the | 708 | This function ignores text display directionality; it returns the |
| 709 | position of the first character in logical order, i.e. the smallest | 709 | position of the first character in logical order, i.e. the smallest |
| 710 | character position on the line. | 710 | character position on the logical line. See `vertical-motion' for |
| 711 | movement by screen lines. | ||
| 711 | 712 | ||
| 712 | This function constrains the returned position to the current field | 713 | This function constrains the returned position to the current field |
| 713 | unless that position would be on a different line from the original, | 714 | unless that position would be on a different line from the original, |
diff --git a/src/image.c b/src/image.c index 643b3d0a1f4..123de54ba27 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -1633,7 +1633,7 @@ search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash) | |||
| 1633 | 1633 | ||
| 1634 | for (img = c->buckets[i]; img; img = img->next) | 1634 | for (img = c->buckets[i]; img; img = img->next) |
| 1635 | if (img->hash == hash | 1635 | if (img->hash == hash |
| 1636 | && !equal_lists (img->spec, spec) | 1636 | && equal_lists (img->spec, spec) |
| 1637 | && img->frame_foreground == FRAME_FOREGROUND_PIXEL (f) | 1637 | && img->frame_foreground == FRAME_FOREGROUND_PIXEL (f) |
| 1638 | && img->frame_background == FRAME_BACKGROUND_PIXEL (f)) | 1638 | && img->frame_background == FRAME_BACKGROUND_PIXEL (f)) |
| 1639 | break; | 1639 | break; |
diff --git a/src/minibuf.c b/src/minibuf.c index e18ff17abbf..f957b2ae173 100644 --- a/src/minibuf.c +++ b/src/minibuf.c | |||
| @@ -1039,7 +1039,7 @@ Prompt with PROMPT. */) | |||
| 1039 | DEFUN ("read-variable", Fread_variable, Sread_variable, 1, 2, 0, | 1039 | DEFUN ("read-variable", Fread_variable, Sread_variable, 1, 2, 0, |
| 1040 | doc: /* Read the name of a user option and return it as a symbol. | 1040 | doc: /* Read the name of a user option and return it as a symbol. |
| 1041 | Prompt with PROMPT. By default, return DEFAULT-VALUE or its first element | 1041 | Prompt with PROMPT. By default, return DEFAULT-VALUE or its first element |
| 1042 | if it is a list. | 1042 | if it is a list of strings. |
| 1043 | A user option, or customizable variable, is one for which | 1043 | A user option, or customizable variable, is one for which |
| 1044 | `custom-variable-p' returns non-nil. */) | 1044 | `custom-variable-p' returns non-nil. */) |
| 1045 | (Lisp_Object prompt, Lisp_Object default_value) | 1045 | (Lisp_Object prompt, Lisp_Object default_value) |
diff --git a/src/nsfns.m b/src/nsfns.m index 628233ea0dd..c7956497c4c 100644 --- a/src/nsfns.m +++ b/src/nsfns.m | |||
| @@ -390,37 +390,25 @@ ns_set_icon_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) | |||
| 390 | /* Don't change the name if it's already NAME. */ | 390 | /* Don't change the name if it's already NAME. */ |
| 391 | if ([[view window] miniwindowTitle] | 391 | if ([[view window] miniwindowTitle] |
| 392 | && ([[[view window] miniwindowTitle] | 392 | && ([[[view window] miniwindowTitle] |
| 393 | isEqualToString: [NSString stringWithUTF8String: | 393 | isEqualToString: [NSString stringWithLispString:arg]])) |
| 394 | SSDATA (arg)]])) | ||
| 395 | return; | 394 | return; |
| 396 | 395 | ||
| 397 | [[view window] setMiniwindowTitle: | 396 | [[view window] setMiniwindowTitle: |
| 398 | [NSString stringWithUTF8String: SSDATA (arg)]]; | 397 | [NSString stringWithLispString:arg]]; |
| 399 | } | 398 | } |
| 400 | 399 | ||
| 401 | static void | 400 | static void |
| 402 | ns_set_name_internal (struct frame *f, Lisp_Object name) | 401 | ns_set_name_internal (struct frame *f, Lisp_Object name) |
| 403 | { | 402 | { |
| 404 | Lisp_Object encoded_name, encoded_icon_name; | ||
| 405 | NSString *str; | ||
| 406 | NSView *view = FRAME_NS_VIEW (f); | 403 | NSView *view = FRAME_NS_VIEW (f); |
| 407 | 404 | NSString *str = [NSString stringWithLispString: name]; | |
| 408 | |||
| 409 | encoded_name = ENCODE_UTF_8 (name); | ||
| 410 | |||
| 411 | str = [NSString stringWithUTF8String: SSDATA (encoded_name)]; | ||
| 412 | |||
| 413 | 405 | ||
| 414 | /* Don't change the name if it's already NAME. */ | 406 | /* Don't change the name if it's already NAME. */ |
| 415 | if (! [[[view window] title] isEqualToString: str]) | 407 | if (! [[[view window] title] isEqualToString: str]) |
| 416 | [[view window] setTitle: str]; | 408 | [[view window] setTitle: str]; |
| 417 | 409 | ||
| 418 | if (!STRINGP (f->icon_name)) | 410 | if (STRINGP (f->icon_name)) |
| 419 | encoded_icon_name = encoded_name; | 411 | str = [NSString stringWithLispString: f->icon_name]; |
| 420 | else | ||
| 421 | encoded_icon_name = ENCODE_UTF_8 (f->icon_name); | ||
| 422 | |||
| 423 | str = [NSString stringWithUTF8String: SSDATA (encoded_icon_name)]; | ||
| 424 | 412 | ||
| 425 | if ([[view window] miniwindowTitle] | 413 | if ([[view window] miniwindowTitle] |
| 426 | && ! [[[view window] miniwindowTitle] isEqualToString: str]) | 414 | && ! [[[view window] miniwindowTitle] isEqualToString: str]) |
| @@ -448,7 +436,7 @@ ns_set_name (struct frame *f, Lisp_Object name, int explicit) | |||
| 448 | return; | 436 | return; |
| 449 | 437 | ||
| 450 | if (NILP (name)) | 438 | if (NILP (name)) |
| 451 | name = build_string ([ns_app_name UTF8String]); | 439 | name = [ns_app_name lispString]; |
| 452 | else | 440 | else |
| 453 | CHECK_STRING (name); | 441 | CHECK_STRING (name); |
| 454 | 442 | ||
| @@ -487,7 +475,7 @@ ns_set_represented_filename (struct frame *f) | |||
| 487 | { | 475 | { |
| 488 | encoded_filename = ENCODE_UTF_8 (filename); | 476 | encoded_filename = ENCODE_UTF_8 (filename); |
| 489 | 477 | ||
| 490 | fstr = [NSString stringWithUTF8String: SSDATA (encoded_filename)]; | 478 | fstr = [NSString stringWithLispString:encoded_filename]; |
| 491 | if (fstr == nil) fstr = @""; | 479 | if (fstr == nil) fstr = @""; |
| 492 | } | 480 | } |
| 493 | else | 481 | else |
| @@ -734,7 +722,7 @@ ns_implicitly_set_icon_type (struct frame *f) | |||
| 734 | block_input (); | 722 | block_input (); |
| 735 | pool = [[NSAutoreleasePool alloc] init]; | 723 | pool = [[NSAutoreleasePool alloc] init]; |
| 736 | if (f->output_data.ns->miniimage | 724 | if (f->output_data.ns->miniimage |
| 737 | && [[NSString stringWithUTF8String: SSDATA (f->name)] | 725 | && [[NSString stringWithLispString:f->name] |
| 738 | isEqualToString: [(NSImage *)f->output_data.ns->miniimage name]]) | 726 | isEqualToString: [(NSImage *)f->output_data.ns->miniimage name]]) |
| 739 | { | 727 | { |
| 740 | [pool release]; | 728 | [pool release]; |
| @@ -759,7 +747,7 @@ ns_implicitly_set_icon_type (struct frame *f) | |||
| 759 | if (SYMBOLP (elt) && EQ (elt, Qt) && SSDATA (f->name)[0] == '/') | 747 | if (SYMBOLP (elt) && EQ (elt, Qt) && SSDATA (f->name)[0] == '/') |
| 760 | { | 748 | { |
| 761 | NSString *str | 749 | NSString *str |
| 762 | = [NSString stringWithUTF8String: SSDATA (f->name)]; | 750 | = [NSString stringWithLispString:f->name]; |
| 763 | if ([[NSFileManager defaultManager] fileExistsAtPath: str]) | 751 | if ([[NSFileManager defaultManager] fileExistsAtPath: str]) |
| 764 | image = [[[NSWorkspace sharedWorkspace] iconForFile: str] retain]; | 752 | image = [[[NSWorkspace sharedWorkspace] iconForFile: str] retain]; |
| 765 | } | 753 | } |
| @@ -771,8 +759,7 @@ ns_implicitly_set_icon_type (struct frame *f) | |||
| 771 | image = [EmacsImage allocInitFromFile: XCDR (elt)]; | 759 | image = [EmacsImage allocInitFromFile: XCDR (elt)]; |
| 772 | if (image == nil) | 760 | if (image == nil) |
| 773 | image = [[NSImage imageNamed: | 761 | image = [[NSImage imageNamed: |
| 774 | [NSString stringWithUTF8String: | 762 | [NSString stringWithLispString:XCDR (elt)]] retain]; |
| 775 | SSDATA (XCDR (elt))]] retain]; | ||
| 776 | } | 763 | } |
| 777 | } | 764 | } |
| 778 | 765 | ||
| @@ -816,8 +803,7 @@ ns_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval) | |||
| 816 | 803 | ||
| 817 | image = [EmacsImage allocInitFromFile: arg]; | 804 | image = [EmacsImage allocInitFromFile: arg]; |
| 818 | if (image == nil) | 805 | if (image == nil) |
| 819 | image =[NSImage imageNamed: [NSString stringWithUTF8String: | 806 | image =[NSImage imageNamed: [NSString stringWithLispString:arg]]; |
| 820 | SSDATA (arg)]]; | ||
| 821 | 807 | ||
| 822 | if (image == nil) | 808 | if (image == nil) |
| 823 | { | 809 | { |
| @@ -851,20 +837,18 @@ ns_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval) | |||
| 851 | static Lisp_Object | 837 | static Lisp_Object |
| 852 | ns_appkit_version_str (void) | 838 | ns_appkit_version_str (void) |
| 853 | { | 839 | { |
| 854 | char tmp[256]; | 840 | NSString *tmp; |
| 855 | 841 | ||
| 856 | #ifdef NS_IMPL_GNUSTEP | 842 | #ifdef NS_IMPL_GNUSTEP |
| 857 | sprintf(tmp, "gnustep-gui-%s", Xstr(GNUSTEP_GUI_VERSION)); | 843 | tmp = [NSString stringWithFormat:@"gnustep-gui-%s", Xstr(GNUSTEP_GUI_VERSION)]; |
| 858 | #elif defined (NS_IMPL_COCOA) | 844 | #elif defined (NS_IMPL_COCOA) |
| 859 | NSString *osversion | 845 | tmp = [NSString stringWithFormat:@"appkit-%.2f %@", |
| 860 | = [[NSProcessInfo processInfo] operatingSystemVersionString]; | 846 | NSAppKitVersionNumber, |
| 861 | sprintf(tmp, "appkit-%.2f %s", | 847 | [[NSProcessInfo processInfo] operatingSystemVersionString]]; |
| 862 | NSAppKitVersionNumber, | ||
| 863 | [osversion UTF8String]); | ||
| 864 | #else | 848 | #else |
| 865 | tmp = "ns-unknown"; | 849 | tmp = [NSString initWithUTF8String:@"ns-unknown"]; |
| 866 | #endif | 850 | #endif |
| 867 | return build_string (tmp); | 851 | return [tmp lispString]; |
| 868 | } | 852 | } |
| 869 | 853 | ||
| 870 | 854 | ||
| @@ -1168,7 +1152,7 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, | |||
| 1168 | be set. */ | 1152 | be set. */ |
| 1169 | if (EQ (name, Qunbound) || NILP (name) || ! STRINGP (name)) | 1153 | if (EQ (name, Qunbound) || NILP (name) || ! STRINGP (name)) |
| 1170 | { | 1154 | { |
| 1171 | fset_name (f, build_string ([ns_app_name UTF8String])); | 1155 | fset_name (f, [ns_app_name lispString]); |
| 1172 | f->explicit_name = 0; | 1156 | f->explicit_name = 0; |
| 1173 | } | 1157 | } |
| 1174 | else | 1158 | else |
| @@ -1609,12 +1593,12 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */) | |||
| 1609 | Lisp_Object fname = Qnil; | 1593 | Lisp_Object fname = Qnil; |
| 1610 | 1594 | ||
| 1611 | NSString *promptS = NILP (prompt) || !STRINGP (prompt) ? nil : | 1595 | NSString *promptS = NILP (prompt) || !STRINGP (prompt) ? nil : |
| 1612 | [NSString stringWithUTF8String: SSDATA (prompt)]; | 1596 | [NSString stringWithLispString:prompt]; |
| 1613 | NSString *dirS = NILP (dir) || !STRINGP (dir) ? | 1597 | NSString *dirS = NILP (dir) || !STRINGP (dir) ? |
| 1614 | [NSString stringWithUTF8String: SSDATA (BVAR (current_buffer, directory))] : | 1598 | [NSString stringWithLispString:BVAR (current_buffer, directory)] : |
| 1615 | [NSString stringWithUTF8String: SSDATA (dir)]; | 1599 | [NSString stringWithLispString:dir]; |
| 1616 | NSString *initS = NILP (init) || !STRINGP (init) ? nil : | 1600 | NSString *initS = NILP (init) || !STRINGP (init) ? nil : |
| 1617 | [NSString stringWithUTF8String: SSDATA (init)]; | 1601 | [NSString stringWithLispString:init]; |
| 1618 | NSEvent *nxev; | 1602 | NSEvent *nxev; |
| 1619 | 1603 | ||
| 1620 | check_window_system (NULL); | 1604 | check_window_system (NULL); |
| @@ -1690,7 +1674,7 @@ Optional arg DIR_ONLY_P, if non-nil, means choose only directories. */) | |||
| 1690 | { | 1674 | { |
| 1691 | NSString *str = ns_filename_from_panel (panel); | 1675 | NSString *str = ns_filename_from_panel (panel); |
| 1692 | if (! str) str = ns_directory_from_panel (panel); | 1676 | if (! str) str = ns_directory_from_panel (panel); |
| 1693 | if (str) fname = build_string ([str UTF8String]); | 1677 | if (str) fname = [str lispString]; |
| 1694 | } | 1678 | } |
| 1695 | 1679 | ||
| 1696 | [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow]; | 1680 | [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow]; |
| @@ -1720,7 +1704,7 @@ If OWNER is nil, Emacs is assumed. */) | |||
| 1720 | 1704 | ||
| 1721 | check_window_system (NULL); | 1705 | check_window_system (NULL); |
| 1722 | if (NILP (owner)) | 1706 | if (NILP (owner)) |
| 1723 | owner = build_string([ns_app_name UTF8String]); | 1707 | owner = [ns_app_name lispString]; |
| 1724 | CHECK_STRING (name); | 1708 | CHECK_STRING (name); |
| 1725 | 1709 | ||
| 1726 | value = ns_get_defaults_value (SSDATA (name)); | 1710 | value = ns_get_defaults_value (SSDATA (name)); |
| @@ -1739,20 +1723,19 @@ If VALUE is nil, the default is removed. */) | |||
| 1739 | { | 1723 | { |
| 1740 | check_window_system (NULL); | 1724 | check_window_system (NULL); |
| 1741 | if (NILP (owner)) | 1725 | if (NILP (owner)) |
| 1742 | owner = build_string ([ns_app_name UTF8String]); | 1726 | owner = [ns_app_name lispString]; |
| 1743 | CHECK_STRING (name); | 1727 | CHECK_STRING (name); |
| 1744 | if (NILP (value)) | 1728 | if (NILP (value)) |
| 1745 | { | 1729 | { |
| 1746 | [[NSUserDefaults standardUserDefaults] removeObjectForKey: | 1730 | [[NSUserDefaults standardUserDefaults] removeObjectForKey: |
| 1747 | [NSString stringWithUTF8String: SSDATA (name)]]; | 1731 | [NSString stringWithLispString:name]]; |
| 1748 | } | 1732 | } |
| 1749 | else | 1733 | else |
| 1750 | { | 1734 | { |
| 1751 | CHECK_STRING (value); | 1735 | CHECK_STRING (value); |
| 1752 | [[NSUserDefaults standardUserDefaults] setObject: | 1736 | [[NSUserDefaults standardUserDefaults] setObject: |
| 1753 | [NSString stringWithUTF8String: SSDATA (value)] | 1737 | [NSString stringWithLispString:value] |
| 1754 | forKey: [NSString stringWithUTF8String: | 1738 | forKey: [NSString stringWithLispString:name]]; |
| 1755 | SSDATA (name)]]; | ||
| 1756 | } | 1739 | } |
| 1757 | 1740 | ||
| 1758 | return Qnil; | 1741 | return Qnil; |
| @@ -2044,7 +2027,7 @@ The optional argument FRAME is currently ignored. */) | |||
| 2044 | NSEnumerator *cnames = [[clist allKeys] reverseObjectEnumerator]; | 2027 | NSEnumerator *cnames = [[clist allKeys] reverseObjectEnumerator]; |
| 2045 | NSString *cname; | 2028 | NSString *cname; |
| 2046 | while ((cname = [cnames nextObject])) | 2029 | while ((cname = [cnames nextObject])) |
| 2047 | list = Fcons (build_string ([cname UTF8String]), list); | 2030 | list = Fcons ([cname lispString], list); |
| 2048 | /* for (i = [[clist allKeys] count] - 1; i >= 0; i--) | 2031 | /* for (i = [[clist allKeys] count] - 1; i >= 0; i--) |
| 2049 | list = Fcons (build_string ([[[clist allKeys] objectAtIndex: i] | 2032 | list = Fcons (build_string ([[[clist allKeys] objectAtIndex: i] |
| 2050 | UTF8String]), list); */ | 2033 | UTF8String]), list); */ |
| @@ -2092,13 +2075,11 @@ there was no result. */) | |||
| 2092 | { | 2075 | { |
| 2093 | id pb; | 2076 | id pb; |
| 2094 | NSString *svcName; | 2077 | NSString *svcName; |
| 2095 | char *utfStr; | ||
| 2096 | 2078 | ||
| 2097 | CHECK_STRING (service); | 2079 | CHECK_STRING (service); |
| 2098 | check_window_system (NULL); | 2080 | check_window_system (NULL); |
| 2099 | 2081 | ||
| 2100 | utfStr = SSDATA (service); | 2082 | svcName = [NSString stringWithLispString:service]; |
| 2101 | svcName = [NSString stringWithUTF8String: utfStr]; | ||
| 2102 | 2083 | ||
| 2103 | pb =[NSPasteboard pasteboardWithUniqueName]; | 2084 | pb =[NSPasteboard pasteboardWithUniqueName]; |
| 2104 | ns_string_to_pasteboard (pb, send); | 2085 | ns_string_to_pasteboard (pb, send); |
| @@ -2128,7 +2109,7 @@ ns_do_applescript (Lisp_Object script, Lisp_Object *result) | |||
| 2128 | 2109 | ||
| 2129 | NSAppleScript *scriptObject = | 2110 | NSAppleScript *scriptObject = |
| 2130 | [[NSAppleScript alloc] initWithSource: | 2111 | [[NSAppleScript alloc] initWithSource: |
| 2131 | [NSString stringWithUTF8String: SSDATA (script)]]; | 2112 | [NSString stringWithLispString:script]]; |
| 2132 | 2113 | ||
| 2133 | returnDescriptor = [scriptObject executeAndReturnError: &errorDict]; | 2114 | returnDescriptor = [scriptObject executeAndReturnError: &errorDict]; |
| 2134 | [scriptObject release]; | 2115 | [scriptObject release]; |
| @@ -2151,7 +2132,7 @@ ns_do_applescript (Lisp_Object script, Lisp_Object *result) | |||
| 2151 | { | 2132 | { |
| 2152 | desc = [returnDescriptor coerceToDescriptorType: typeUTF8Text]; | 2133 | desc = [returnDescriptor coerceToDescriptorType: typeUTF8Text]; |
| 2153 | if (desc) | 2134 | if (desc) |
| 2154 | *result = build_string([[desc stringValue] UTF8String]); | 2135 | *result = [[desc stringValue] lispString]; |
| 2155 | } | 2136 | } |
| 2156 | else | 2137 | else |
| 2157 | { | 2138 | { |
| @@ -3031,6 +3012,60 @@ DEFUN ("ns-show-character-palette", | |||
| 3031 | #endif | 3012 | #endif |
| 3032 | 3013 | ||
| 3033 | 3014 | ||
| 3015 | /* Whether N bytes at STR are in the [0,127] range. */ | ||
| 3016 | static bool | ||
| 3017 | all_nonzero_ascii (unsigned char *str, ptrdiff_t n) | ||
| 3018 | { | ||
| 3019 | for (ptrdiff_t i = 0; i < n; i++) | ||
| 3020 | if (str[i] < 1 || str[i] > 127) | ||
| 3021 | return false; | ||
| 3022 | return true; | ||
| 3023 | } | ||
| 3024 | |||
| 3025 | @implementation NSString (EmacsString) | ||
| 3026 | /* Make an NSString from a Lisp string. */ | ||
| 3027 | + (NSString *)stringWithLispString:(Lisp_Object)string | ||
| 3028 | { | ||
| 3029 | /* Shortcut for the common case. */ | ||
| 3030 | if (all_nonzero_ascii (SDATA (string), SBYTES (string))) | ||
| 3031 | return [NSString stringWithCString: SSDATA (string) | ||
| 3032 | encoding: NSASCIIStringEncoding]; | ||
| 3033 | string = string_to_multibyte (string); | ||
| 3034 | |||
| 3035 | /* Now the string is multibyte; convert to UTF-16. */ | ||
| 3036 | unichar *chars = xmalloc (4 * SCHARS (string)); | ||
| 3037 | unichar *d = chars; | ||
| 3038 | const unsigned char *s = SDATA (string); | ||
| 3039 | const unsigned char *end = s + SBYTES (string); | ||
| 3040 | while (s < end) | ||
| 3041 | { | ||
| 3042 | int c = string_char_advance (&s); | ||
| 3043 | /* We pass unpaired surrogates through, because they are typically | ||
| 3044 | handled fairly well by the NS libraries (displayed with distinct | ||
| 3045 | glyphs etc). */ | ||
| 3046 | if (c <= 0xffff) | ||
| 3047 | *d++ = c; | ||
| 3048 | else if (c <= 0x10ffff) | ||
| 3049 | { | ||
| 3050 | *d++ = 0xd800 + ((c - 0x10000) >> 10); | ||
| 3051 | *d++ = 0xdc00 + (c & 0x3ff); | ||
| 3052 | } | ||
| 3053 | else | ||
| 3054 | *d++ = 0xfffd; /* Not valid for UTF-16. */ | ||
| 3055 | } | ||
| 3056 | NSString *str = [NSString stringWithCharacters: chars | ||
| 3057 | length: d - chars]; | ||
| 3058 | xfree (chars); | ||
| 3059 | return str; | ||
| 3060 | } | ||
| 3061 | |||
| 3062 | /* Make a Lisp string from an NSString. */ | ||
| 3063 | - (Lisp_Object)lispString | ||
| 3064 | { | ||
| 3065 | return build_string ([self UTF8String]); | ||
| 3066 | } | ||
| 3067 | @end | ||
| 3068 | |||
| 3034 | /* ========================================================================== | 3069 | /* ========================================================================== |
| 3035 | 3070 | ||
| 3036 | Lisp interface declaration | 3071 | Lisp interface declaration |
diff --git a/src/nsterm.h b/src/nsterm.h index a511fef5b98..b56bcad4dc1 100644 --- a/src/nsterm.h +++ b/src/nsterm.h | |||
| @@ -361,6 +361,12 @@ typedef id instancetype; | |||
| 361 | 361 | ||
| 362 | @end | 362 | @end |
| 363 | 363 | ||
| 364 | |||
| 365 | @interface NSString (EmacsString) | ||
| 366 | + (NSString *)stringWithLispString:(Lisp_Object)string; | ||
| 367 | - (Lisp_Object)lispString; | ||
| 368 | @end | ||
| 369 | |||
| 364 | /* ========================================================================== | 370 | /* ========================================================================== |
| 365 | 371 | ||
| 366 | The Emacs application | 372 | The Emacs application |
diff --git a/src/nsterm.m b/src/nsterm.m index 98c5b69d681..26059ab67cd 100644 --- a/src/nsterm.m +++ b/src/nsterm.m | |||
| @@ -5909,7 +5909,7 @@ ns_term_shutdown (int sig) | |||
| 5909 | 5909 | ||
| 5910 | emacs_event->kind = NS_NONKEY_EVENT; | 5910 | emacs_event->kind = NS_NONKEY_EVENT; |
| 5911 | emacs_event->code = KEY_NS_OPEN_FILE_LINE; | 5911 | emacs_event->code = KEY_NS_OPEN_FILE_LINE; |
| 5912 | ns_input_file = append2 (ns_input_file, build_string ([fileName UTF8String])); | 5912 | ns_input_file = append2 (ns_input_file, [fileName lispString]); |
| 5913 | ns_input_line = Qnil; /* can be start or cons start,end */ | 5913 | ns_input_line = Qnil; /* can be start or cons start,end */ |
| 5914 | emacs_event->modifiers =0; | 5914 | emacs_event->modifiers =0; |
| 5915 | EV_TRAILER (theEvent); | 5915 | EV_TRAILER (theEvent); |
| @@ -6273,8 +6273,7 @@ not_in_argv (NSString *arg) | |||
| 6273 | error: (NSString **)error | 6273 | error: (NSString **)error |
| 6274 | { | 6274 | { |
| 6275 | [ns_pending_service_names addObject: userData]; | 6275 | [ns_pending_service_names addObject: userData]; |
| 6276 | [ns_pending_service_args addObject: [NSString stringWithUTF8String: | 6276 | [ns_pending_service_args addObject: [NSString stringWithLispString:ns_string_from_pasteboard (pboard)]]; |
| 6277 | SSDATA (ns_string_from_pasteboard (pboard))]]; | ||
| 6278 | } | 6277 | } |
| 6279 | 6278 | ||
| 6280 | 6279 | ||
| @@ -6291,8 +6290,8 @@ not_in_argv (NSString *arg) | |||
| 6291 | 6290 | ||
| 6292 | emacs_event->kind = NS_NONKEY_EVENT; | 6291 | emacs_event->kind = NS_NONKEY_EVENT; |
| 6293 | emacs_event->code = KEY_NS_SPI_SERVICE_CALL; | 6292 | emacs_event->code = KEY_NS_SPI_SERVICE_CALL; |
| 6294 | ns_input_spi_name = build_string ([name UTF8String]); | 6293 | ns_input_spi_name = [name lispString]; |
| 6295 | ns_input_spi_arg = build_string ([arg UTF8String]); | 6294 | ns_input_spi_arg = [arg lispString]; |
| 6296 | emacs_event->modifiers = EV_MODIFIERS (theEvent); | 6295 | emacs_event->modifiers = EV_MODIFIERS (theEvent); |
| 6297 | EV_TRAILER (theEvent); | 6296 | EV_TRAILER (theEvent); |
| 6298 | 6297 | ||
| @@ -6374,7 +6373,7 @@ not_in_argv (NSString *arg) | |||
| 6374 | 6373 | ||
| 6375 | size = [newFont pointSize]; | 6374 | size = [newFont pointSize]; |
| 6376 | ns_input_fontsize = make_fixnum (lrint (size)); | 6375 | ns_input_fontsize = make_fixnum (lrint (size)); |
| 6377 | ns_input_font = build_string ([[newFont familyName] UTF8String]); | 6376 | ns_input_font = [[newFont familyName] lispString]; |
| 6378 | EV_TRAILER (e); | 6377 | EV_TRAILER (e); |
| 6379 | } | 6378 | } |
| 6380 | } | 6379 | } |
| @@ -6685,7 +6684,7 @@ not_in_argv (NSString *arg) | |||
| 6685 | processingCompose = YES; | 6684 | processingCompose = YES; |
| 6686 | [workingText release]; | 6685 | [workingText release]; |
| 6687 | workingText = [str copy]; | 6686 | workingText = [str copy]; |
| 6688 | ns_working_text = build_string ([workingText UTF8String]); | 6687 | ns_working_text = [workingText lispString]; |
| 6689 | 6688 | ||
| 6690 | emacs_event->kind = NS_TEXT_EVENT; | 6689 | emacs_event->kind = NS_TEXT_EVENT; |
| 6691 | emacs_event->code = KEY_NS_PUT_WORKING_TEXT; | 6690 | emacs_event->code = KEY_NS_PUT_WORKING_TEXT; |
| @@ -7605,7 +7604,7 @@ not_in_argv (NSString *arg) | |||
| 7605 | tem = f->icon_name; | 7604 | tem = f->icon_name; |
| 7606 | if (!NILP (tem)) | 7605 | if (!NILP (tem)) |
| 7607 | [win setMiniwindowTitle: | 7606 | [win setMiniwindowTitle: |
| 7608 | [NSString stringWithUTF8String: SSDATA (tem)]]; | 7607 | [NSString stringWithLispString:tem]]; |
| 7609 | 7608 | ||
| 7610 | if (FRAME_PARENT_FRAME (f) != NULL) | 7609 | if (FRAME_PARENT_FRAME (f) != NULL) |
| 7611 | { | 7610 | { |
| @@ -8609,7 +8608,7 @@ not_in_argv (NSString *arg) | |||
| 8609 | 8608 | ||
| 8610 | fenum = [files objectEnumerator]; | 8609 | fenum = [files objectEnumerator]; |
| 8611 | while ( (file = [fenum nextObject]) ) | 8610 | while ( (file = [fenum nextObject]) ) |
| 8612 | strings = Fcons (build_string ([file UTF8String]), strings); | 8611 | strings = Fcons ([file lispString], strings); |
| 8613 | } | 8612 | } |
| 8614 | else if ([type isEqualToString: NSURLPboardType]) | 8613 | else if ([type isEqualToString: NSURLPboardType]) |
| 8615 | { | 8614 | { |
| @@ -8618,7 +8617,7 @@ not_in_argv (NSString *arg) | |||
| 8618 | 8617 | ||
| 8619 | type_sym = Qurl; | 8618 | type_sym = Qurl; |
| 8620 | 8619 | ||
| 8621 | strings = list1 (build_string ([[url absoluteString] UTF8String])); | 8620 | strings = list1 ([[url absoluteString] lispString]); |
| 8622 | } | 8621 | } |
| 8623 | else if ([type isEqualToString: NSStringPboardType] | 8622 | else if ([type isEqualToString: NSStringPboardType] |
| 8624 | || [type isEqualToString: NSTabularTextPboardType]) | 8623 | || [type isEqualToString: NSTabularTextPboardType]) |
| @@ -8630,7 +8629,7 @@ not_in_argv (NSString *arg) | |||
| 8630 | 8629 | ||
| 8631 | type_sym = Qnil; | 8630 | type_sym = Qnil; |
| 8632 | 8631 | ||
| 8633 | strings = list1 (build_string ([data UTF8String])); | 8632 | strings = list1 ([data lispString]); |
| 8634 | } | 8633 | } |
| 8635 | else | 8634 | else |
| 8636 | { | 8635 | { |
| @@ -8802,9 +8801,7 @@ not_in_argv (NSString *arg) | |||
| 8802 | } | 8801 | } |
| 8803 | if (STRINGP (str)) | 8802 | if (STRINGP (str)) |
| 8804 | { | 8803 | { |
| 8805 | const char *utfStr = SSDATA (str); | 8804 | return [NSString stringWithLispString:str]; |
| 8806 | NSString *nsStr = [NSString stringWithUTF8String: utfStr]; | ||
| 8807 | return nsStr; | ||
| 8808 | } | 8805 | } |
| 8809 | } | 8806 | } |
| 8810 | 8807 | ||
diff --git a/src/process.c b/src/process.c index 15634e4a8b0..3aa105ae342 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -1654,7 +1654,10 @@ you specify a filter function to handle the output. BUFFER may be | |||
| 1654 | also nil, meaning that this process is not associated with any buffer. | 1654 | also nil, meaning that this process is not associated with any buffer. |
| 1655 | 1655 | ||
| 1656 | :command COMMAND -- COMMAND is a list starting with the program file | 1656 | :command COMMAND -- COMMAND is a list starting with the program file |
| 1657 | name, followed by strings to give to the program as arguments. | 1657 | name, followed by strings to give to the program as arguments. If the |
| 1658 | program file name is not an absolute file name, `make-process' will | ||
| 1659 | look for the program file name in `exec-path' (which is a list of | ||
| 1660 | directories). | ||
| 1658 | 1661 | ||
| 1659 | :coding CODING -- If CODING is a symbol, it specifies the coding | 1662 | :coding CODING -- If CODING is a symbol, it specifies the coding |
| 1660 | system used for both reading and writing for this process. If CODING | 1663 | system used for both reading and writing for this process. If CODING |
diff --git a/src/thread.c b/src/thread.c index b638dd77f8b..7ab1e6de1fc 100644 --- a/src/thread.c +++ b/src/thread.c | |||
| @@ -28,6 +28,12 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 28 | #include "pdumper.h" | 28 | #include "pdumper.h" |
| 29 | #include "keyboard.h" | 29 | #include "keyboard.h" |
| 30 | 30 | ||
| 31 | #if defined HAVE_GLIB && ! defined (HAVE_NS) | ||
| 32 | #include <xgselect.h> | ||
| 33 | #else | ||
| 34 | #define release_select_lock() do { } while (0) | ||
| 35 | #endif | ||
| 36 | |||
| 31 | union aligned_thread_state | 37 | union aligned_thread_state |
| 32 | { | 38 | { |
| 33 | struct thread_state s; | 39 | struct thread_state s; |
| @@ -586,6 +592,8 @@ really_call_select (void *arg) | |||
| 586 | sa->result = (sa->func) (sa->max_fds, sa->rfds, sa->wfds, sa->efds, | 592 | sa->result = (sa->func) (sa->max_fds, sa->rfds, sa->wfds, sa->efds, |
| 587 | sa->timeout, sa->sigmask); | 593 | sa->timeout, sa->sigmask); |
| 588 | 594 | ||
| 595 | release_select_lock (); | ||
| 596 | |||
| 589 | block_interrupt_signal (&oldset); | 597 | block_interrupt_signal (&oldset); |
| 590 | /* If we were interrupted by C-g while inside sa->func above, the | 598 | /* If we were interrupted by C-g while inside sa->func above, the |
| 591 | signal handler could have called maybe_reacquire_global_lock, in | 599 | signal handler could have called maybe_reacquire_global_lock, in |
diff --git a/src/xdisp.c b/src/xdisp.c index ad03ac46054..a1f7706ead2 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -447,6 +447,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 447 | #include "termchar.h" | 447 | #include "termchar.h" |
| 448 | #include "dispextern.h" | 448 | #include "dispextern.h" |
| 449 | #include "character.h" | 449 | #include "character.h" |
| 450 | #include "category.h" | ||
| 450 | #include "buffer.h" | 451 | #include "buffer.h" |
| 451 | #include "charset.h" | 452 | #include "charset.h" |
| 452 | #include "indent.h" | 453 | #include "indent.h" |
| @@ -508,6 +509,80 @@ static Lisp_Object list_of_error; | |||
| 508 | && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \ | 509 | && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \ |
| 509 | || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) | 510 | || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) |
| 510 | 511 | ||
| 512 | /* These are the category sets we use. They are defined by | ||
| 513 | kinsoku.el and chracters.el. */ | ||
| 514 | #define NOT_AT_EOL '<' | ||
| 515 | #define NOT_AT_BOL '>' | ||
| 516 | #define LINE_BREAKABLE '|' | ||
| 517 | |||
| 518 | static bool | ||
| 519 | it_char_has_category(struct it *it, int cat) | ||
| 520 | { | ||
| 521 | int ch = 0; | ||
| 522 | if (it->what == IT_CHARACTER) | ||
| 523 | ch = it->c; | ||
| 524 | else if (STRINGP (it->string)) | ||
| 525 | ch = SREF (it->string, IT_STRING_BYTEPOS (*it)); | ||
| 526 | else if (it->s) | ||
| 527 | ch = it->s[IT_BYTEPOS (*it)]; | ||
| 528 | else if (IT_BYTEPOS (*it) < ZV_BYTE) | ||
| 529 | ch = *BYTE_POS_ADDR (IT_BYTEPOS (*it)); | ||
| 530 | |||
| 531 | if (ch == 0) | ||
| 532 | return false; | ||
| 533 | else | ||
| 534 | return CHAR_HAS_CATEGORY (ch, cat); | ||
| 535 | } | ||
| 536 | |||
| 537 | /* Return true if the current character allows wrapping before it. */ | ||
| 538 | static bool | ||
| 539 | char_can_wrap_before (struct it *it) | ||
| 540 | { | ||
| 541 | if (!Vword_wrap_by_category) | ||
| 542 | return !IT_DISPLAYING_WHITESPACE (it); | ||
| 543 | |||
| 544 | /* For CJK (LTR) text in RTL paragraph, EOL and BOL are flipped. | ||
| 545 | Because in RTL paragraph, each glyph is prepended to the last | ||
| 546 | one, effectively drawing right to left. */ | ||
| 547 | int not_at_bol; | ||
| 548 | if (it->glyph_row && it->glyph_row->reversed_p) | ||
| 549 | not_at_bol = NOT_AT_EOL; | ||
| 550 | else | ||
| 551 | not_at_bol = NOT_AT_BOL; | ||
| 552 | /* You cannot wrap before a space or tab because that way you'll | ||
| 553 | have space and tab at the beginning of next line. */ | ||
| 554 | return (!IT_DISPLAYING_WHITESPACE (it) | ||
| 555 | /* Can be at BOL. */ | ||
| 556 | && !it_char_has_category (it, not_at_bol)); | ||
| 557 | } | ||
| 558 | |||
| 559 | /* Return true if the current character allows wrapping after it. */ | ||
| 560 | static bool | ||
| 561 | char_can_wrap_after (struct it *it) | ||
| 562 | { | ||
| 563 | if (!Vword_wrap_by_category) | ||
| 564 | return IT_DISPLAYING_WHITESPACE (it); | ||
| 565 | |||
| 566 | /* For CJK (LTR) text in RTL paragraph, EOL and BOL are flipped. | ||
| 567 | Because in RTL paragraph, each glyph is prepended to the last | ||
| 568 | one, effectively drawing right to left. */ | ||
| 569 | int not_at_eol; | ||
| 570 | if (it->glyph_row && it->glyph_row->reversed_p) | ||
| 571 | not_at_eol = NOT_AT_BOL; | ||
| 572 | else | ||
| 573 | not_at_eol = NOT_AT_EOL; | ||
| 574 | |||
| 575 | return (IT_DISPLAYING_WHITESPACE (it) | ||
| 576 | /* Can break after && can be at EOL. */ | ||
| 577 | || (it_char_has_category (it, LINE_BREAKABLE) | ||
| 578 | && !it_char_has_category (it, not_at_eol))); | ||
| 579 | } | ||
| 580 | |||
| 581 | #undef IT_DISPLAYING_WHITESPACE | ||
| 582 | #undef NOT_AT_EOL | ||
| 583 | #undef NOT_AT_BOL | ||
| 584 | #undef LINE_BREAKABLE | ||
| 585 | |||
| 511 | /* If all the conditions needed to print the fill column indicator are | 586 | /* If all the conditions needed to print the fill column indicator are |
| 512 | met, return the (nonnegative) column number, else return a negative | 587 | met, return the (nonnegative) column number, else return a negative |
| 513 | value. */ | 588 | value. */ |
| @@ -9193,13 +9268,20 @@ move_it_in_display_line_to (struct it *it, | |||
| 9193 | { | 9268 | { |
| 9194 | if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA) | 9269 | if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA) |
| 9195 | { | 9270 | { |
| 9196 | if (IT_DISPLAYING_WHITESPACE (it)) | 9271 | bool next_may_wrap = may_wrap; |
| 9197 | may_wrap = true; | 9272 | /* Can we wrap after this character? */ |
| 9198 | else if (may_wrap) | 9273 | if (char_can_wrap_after (it)) |
| 9274 | next_may_wrap = true; | ||
| 9275 | else | ||
| 9276 | next_may_wrap = false; | ||
| 9277 | /* Can we wrap here? */ | ||
| 9278 | if (may_wrap && char_can_wrap_before (it)) | ||
| 9199 | { | 9279 | { |
| 9200 | /* We have reached a glyph that follows one or more | 9280 | /* We have reached a glyph that follows one or more |
| 9201 | whitespace characters. If the position is | 9281 | whitespace characters or a character that allows |
| 9202 | already found, we are done. */ | 9282 | wrapping after it. If this character allows |
| 9283 | wrapping before it, save this position as a | ||
| 9284 | wrapping point. */ | ||
| 9203 | if (atpos_it.sp >= 0) | 9285 | if (atpos_it.sp >= 0) |
| 9204 | { | 9286 | { |
| 9205 | RESTORE_IT (it, &atpos_it, atpos_data); | 9287 | RESTORE_IT (it, &atpos_it, atpos_data); |
| @@ -9214,8 +9296,10 @@ move_it_in_display_line_to (struct it *it, | |||
| 9214 | } | 9296 | } |
| 9215 | /* Otherwise, we can wrap here. */ | 9297 | /* Otherwise, we can wrap here. */ |
| 9216 | SAVE_IT (wrap_it, *it, wrap_data); | 9298 | SAVE_IT (wrap_it, *it, wrap_data); |
| 9217 | may_wrap = false; | 9299 | next_may_wrap = false; |
| 9218 | } | 9300 | } |
| 9301 | /* Update may_wrap for the next iteration. */ | ||
| 9302 | may_wrap = next_may_wrap; | ||
| 9219 | } | 9303 | } |
| 9220 | } | 9304 | } |
| 9221 | 9305 | ||
| @@ -9343,10 +9427,10 @@ move_it_in_display_line_to (struct it *it, | |||
| 9343 | { | 9427 | { |
| 9344 | bool can_wrap = true; | 9428 | bool can_wrap = true; |
| 9345 | 9429 | ||
| 9346 | /* If we are at a whitespace character | 9430 | /* If the previous character says we can |
| 9347 | that barely fits on this screen line, | 9431 | wrap after it, but the current |
| 9348 | but the next character is also | 9432 | character says we can't wrap before |
| 9349 | whitespace, we cannot wrap here. */ | 9433 | it, then we can't wrap here. */ |
| 9350 | if (it->line_wrap == WORD_WRAP | 9434 | if (it->line_wrap == WORD_WRAP |
| 9351 | && wrap_it.sp >= 0 | 9435 | && wrap_it.sp >= 0 |
| 9352 | && may_wrap | 9436 | && may_wrap |
| @@ -9358,7 +9442,7 @@ move_it_in_display_line_to (struct it *it, | |||
| 9358 | SAVE_IT (tem_it, *it, tem_data); | 9442 | SAVE_IT (tem_it, *it, tem_data); |
| 9359 | set_iterator_to_next (it, true); | 9443 | set_iterator_to_next (it, true); |
| 9360 | if (get_next_display_element (it) | 9444 | if (get_next_display_element (it) |
| 9361 | && IT_DISPLAYING_WHITESPACE (it)) | 9445 | && !char_can_wrap_before (it)) |
| 9362 | can_wrap = false; | 9446 | can_wrap = false; |
| 9363 | RESTORE_IT (it, &tem_it, tem_data); | 9447 | RESTORE_IT (it, &tem_it, tem_data); |
| 9364 | } | 9448 | } |
| @@ -9437,19 +9521,18 @@ move_it_in_display_line_to (struct it *it, | |||
| 9437 | else | 9521 | else |
| 9438 | IT_RESET_X_ASCENT_DESCENT (it); | 9522 | IT_RESET_X_ASCENT_DESCENT (it); |
| 9439 | 9523 | ||
| 9440 | /* If the screen line ends with whitespace, and we | 9524 | /* If the screen line ends with whitespace (or |
| 9441 | are under word-wrap, don't use wrap_it: it is no | 9525 | wrap-able character), and we are under word-wrap, |
| 9442 | longer relevant, but we won't have an opportunity | 9526 | don't use wrap_it: it is no longer relevant, but |
| 9443 | to update it, since we are done with this screen | 9527 | we won't have an opportunity to update it, since |
| 9444 | line. */ | 9528 | we are done with this screen line. */ |
| 9445 | if (may_wrap && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it) | 9529 | if (may_wrap && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it) |
| 9446 | /* If the character after the one which set the | 9530 | /* If the character after the one which set the |
| 9447 | may_wrap flag is also whitespace, we can't | 9531 | may_wrap flag says we can't wrap before it, |
| 9448 | wrap here, since the screen line cannot be | 9532 | we can't wrap here. Therefore, wrap_it |
| 9449 | wrapped in the middle of whitespace. | 9533 | (previously found wrap-point) _is_ relevant |
| 9450 | Therefore, wrap_it _is_ relevant in that | 9534 | in that case. */ |
| 9451 | case. */ | 9535 | && !(moved_forward && char_can_wrap_before (it))) |
| 9452 | && !(moved_forward && IT_DISPLAYING_WHITESPACE (it))) | ||
| 9453 | { | 9536 | { |
| 9454 | /* If we've found TO_X, go back there, as we now | 9537 | /* If we've found TO_X, go back there, as we now |
| 9455 | know the last word fits on this screen line. */ | 9538 | know the last word fits on this screen line. */ |
| @@ -23322,9 +23405,14 @@ display_line (struct it *it, int cursor_vpos) | |||
| 23322 | 23405 | ||
| 23323 | if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA) | 23406 | if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA) |
| 23324 | { | 23407 | { |
| 23325 | if (IT_DISPLAYING_WHITESPACE (it)) | 23408 | bool next_may_wrap = may_wrap; |
| 23326 | may_wrap = true; | 23409 | /* Can we wrap after this character? */ |
| 23327 | else if (may_wrap) | 23410 | if (char_can_wrap_after (it)) |
| 23411 | next_may_wrap = true; | ||
| 23412 | else | ||
| 23413 | next_may_wrap = false; | ||
| 23414 | /* Can we wrap here? */ | ||
| 23415 | if (may_wrap && char_can_wrap_before (it)) | ||
| 23328 | { | 23416 | { |
| 23329 | SAVE_IT (wrap_it, *it, wrap_data); | 23417 | SAVE_IT (wrap_it, *it, wrap_data); |
| 23330 | wrap_x = x; | 23418 | wrap_x = x; |
| @@ -23338,8 +23426,9 @@ display_line (struct it *it, int cursor_vpos) | |||
| 23338 | wrap_row_min_bpos = min_bpos; | 23426 | wrap_row_min_bpos = min_bpos; |
| 23339 | wrap_row_max_pos = max_pos; | 23427 | wrap_row_max_pos = max_pos; |
| 23340 | wrap_row_max_bpos = max_bpos; | 23428 | wrap_row_max_bpos = max_bpos; |
| 23341 | may_wrap = false; | ||
| 23342 | } | 23429 | } |
| 23430 | /* Update may_wrap for the next iteration. */ | ||
| 23431 | may_wrap = next_may_wrap; | ||
| 23343 | } | 23432 | } |
| 23344 | } | 23433 | } |
| 23345 | 23434 | ||
| @@ -23463,14 +23552,18 @@ display_line (struct it *it, int cursor_vpos) | |||
| 23463 | /* If line-wrap is on, check if a previous | 23552 | /* If line-wrap is on, check if a previous |
| 23464 | wrap point was found. */ | 23553 | wrap point was found. */ |
| 23465 | if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it) | 23554 | if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it) |
| 23466 | && wrap_row_used > 0 | 23555 | && wrap_row_used > 0 /* Found. */ |
| 23467 | /* Even if there is a previous wrap | 23556 | /* Even if there is a previous wrap |
| 23468 | point, continue the line here as | 23557 | point, continue the line here as |
| 23469 | usual, if (i) the previous character | 23558 | usual, if (i) the previous character |
| 23470 | was a space or tab AND (ii) the | 23559 | allows wrapping after it, AND (ii) |
| 23471 | current character is not. */ | 23560 | the current character allows wrapping |
| 23472 | && (!may_wrap | 23561 | before it. Because this is a valid |
| 23473 | || IT_DISPLAYING_WHITESPACE (it))) | 23562 | break point, we can just continue to |
| 23563 | the next line at here, there is no | ||
| 23564 | need to wrap early at the previous | ||
| 23565 | wrap point. */ | ||
| 23566 | && (!may_wrap || !char_can_wrap_before (it))) | ||
| 23474 | goto back_to_wrap; | 23567 | goto back_to_wrap; |
| 23475 | 23568 | ||
| 23476 | /* Record the maximum and minimum buffer | 23569 | /* Record the maximum and minimum buffer |
| @@ -23498,13 +23591,16 @@ display_line (struct it *it, int cursor_vpos) | |||
| 23498 | /* If line-wrap is on, check if a | 23591 | /* If line-wrap is on, check if a |
| 23499 | previous wrap point was found. */ | 23592 | previous wrap point was found. */ |
| 23500 | else if (wrap_row_used > 0 | 23593 | else if (wrap_row_used > 0 |
| 23501 | /* Even if there is a previous wrap | 23594 | /* Even if there is a previous |
| 23502 | point, continue the line here as | 23595 | wrap point, continue the |
| 23503 | usual, if (i) the previous character | 23596 | line here as usual, if (i) |
| 23504 | was a space or tab AND (ii) the | 23597 | the previous character was a |
| 23505 | current character is not. */ | 23598 | space or tab AND (ii) the |
| 23506 | && (!may_wrap | 23599 | current character is not, |
| 23507 | || IT_DISPLAYING_WHITESPACE (it))) | 23600 | AND (iii) the current |
| 23601 | character allows wrapping | ||
| 23602 | before it. */ | ||
| 23603 | && (!may_wrap || !char_can_wrap_before (it))) | ||
| 23508 | goto back_to_wrap; | 23604 | goto back_to_wrap; |
| 23509 | 23605 | ||
| 23510 | } | 23606 | } |
| @@ -34662,6 +34758,23 @@ A value of nil means to respect the value of `truncate-lines'. | |||
| 34662 | If `word-wrap' is enabled, you might want to reduce this. */); | 34758 | If `word-wrap' is enabled, you might want to reduce this. */); |
| 34663 | Vtruncate_partial_width_windows = make_fixnum (50); | 34759 | Vtruncate_partial_width_windows = make_fixnum (50); |
| 34664 | 34760 | ||
| 34761 | DEFVAR_BOOL("word-wrap-by-category", Vword_wrap_by_category, doc: /* | ||
| 34762 | Non-nil means also wrap after characters of a certain category. | ||
| 34763 | Normally when `word-wrap' is on, Emacs only breaks lines after | ||
| 34764 | whitespace characters. When this option is turned on, Emacs also | ||
| 34765 | breaks lines after characters that have the "|" category (defined in | ||
| 34766 | characters.el). This is useful for allowing breaking after CJK | ||
| 34767 | characters and improves the word-wrapping for CJK text mixed with | ||
| 34768 | Latin text. | ||
| 34769 | |||
| 34770 | If this variable is set using Customize, Emacs automatically loads | ||
| 34771 | kinsoku.el. When kinsoku.el is loaded, Emacs respects kinsoku rules | ||
| 34772 | when breaking lines. That means characters with the ">" category | ||
| 34773 | don't appear at the beginning of a line (e.g., FULLWIDTH COMMA), and | ||
| 34774 | characters with the "<" category don't appear at the end of a line | ||
| 34775 | (e.g., LEFT DOUBLE ANGLE BRACKET). */); | ||
| 34776 | Vword_wrap_by_category = false; | ||
| 34777 | |||
| 34665 | DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit, | 34778 | DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit, |
| 34666 | doc: /* Maximum buffer size for which line number should be displayed. | 34779 | doc: /* Maximum buffer size for which line number should be displayed. |
| 34667 | If the buffer is bigger than this, the line number does not appear | 34780 | If the buffer is bigger than this, the line number does not appear |
diff --git a/src/xgselect.c b/src/xgselect.c index f8d0bac7fac..be70107b756 100644 --- a/src/xgselect.c +++ b/src/xgselect.c | |||
| @@ -29,6 +29,27 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 29 | #include "blockinput.h" | 29 | #include "blockinput.h" |
| 30 | #include "systime.h" | 30 | #include "systime.h" |
| 31 | 31 | ||
| 32 | static ptrdiff_t threads_holding_glib_lock; | ||
| 33 | static GMainContext *glib_main_context; | ||
| 34 | |||
| 35 | void release_select_lock (void) | ||
| 36 | { | ||
| 37 | if (--threads_holding_glib_lock == 0) | ||
| 38 | g_main_context_release (glib_main_context); | ||
| 39 | } | ||
| 40 | |||
| 41 | static void acquire_select_lock (GMainContext *context) | ||
| 42 | { | ||
| 43 | if (threads_holding_glib_lock++ == 0) | ||
| 44 | { | ||
| 45 | glib_main_context = context; | ||
| 46 | while (!g_main_context_acquire (context)) | ||
| 47 | { | ||
| 48 | /* Spin. */ | ||
| 49 | } | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 32 | /* `xg_select' is a `pselect' replacement. Why do we need a separate function? | 53 | /* `xg_select' is a `pselect' replacement. Why do we need a separate function? |
| 33 | 1. Timeouts. Glib and Gtk rely on timer events. If we did pselect | 54 | 1. Timeouts. Glib and Gtk rely on timer events. If we did pselect |
| 34 | with a greater timeout then the one scheduled by Glib, we would | 55 | with a greater timeout then the one scheduled by Glib, we would |
| @@ -54,26 +75,19 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds, | |||
| 54 | GPollFD *gfds = gfds_buf; | 75 | GPollFD *gfds = gfds_buf; |
| 55 | int gfds_size = ARRAYELTS (gfds_buf); | 76 | int gfds_size = ARRAYELTS (gfds_buf); |
| 56 | int n_gfds, retval = 0, our_fds = 0, max_fds = fds_lim - 1; | 77 | int n_gfds, retval = 0, our_fds = 0, max_fds = fds_lim - 1; |
| 57 | bool context_acquired = false; | ||
| 58 | int i, nfds, tmo_in_millisec, must_free = 0; | 78 | int i, nfds, tmo_in_millisec, must_free = 0; |
| 59 | bool need_to_dispatch; | 79 | bool need_to_dispatch; |
| 60 | 80 | ||
| 61 | context = g_main_context_default (); | 81 | context = g_main_context_default (); |
| 62 | context_acquired = g_main_context_acquire (context); | 82 | acquire_select_lock (context); |
| 63 | /* FIXME: If we couldn't acquire the context, we just silently proceed | ||
| 64 | because this function handles more than just glib file descriptors. | ||
| 65 | Note that, as implemented, this failure is completely silent: there is | ||
| 66 | no feedback to the caller. */ | ||
| 67 | 83 | ||
| 68 | if (rfds) all_rfds = *rfds; | 84 | if (rfds) all_rfds = *rfds; |
| 69 | else FD_ZERO (&all_rfds); | 85 | else FD_ZERO (&all_rfds); |
| 70 | if (wfds) all_wfds = *wfds; | 86 | if (wfds) all_wfds = *wfds; |
| 71 | else FD_ZERO (&all_wfds); | 87 | else FD_ZERO (&all_wfds); |
| 72 | 88 | ||
| 73 | n_gfds = (context_acquired | 89 | n_gfds = g_main_context_query (context, G_PRIORITY_LOW, &tmo_in_millisec, |
| 74 | ? g_main_context_query (context, G_PRIORITY_LOW, &tmo_in_millisec, | 90 | gfds, gfds_size); |
| 75 | gfds, gfds_size) | ||
| 76 | : -1); | ||
| 77 | 91 | ||
| 78 | if (gfds_size < n_gfds) | 92 | if (gfds_size < n_gfds) |
| 79 | { | 93 | { |
| @@ -151,8 +165,10 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds, | |||
| 151 | #else | 165 | #else |
| 152 | need_to_dispatch = true; | 166 | need_to_dispatch = true; |
| 153 | #endif | 167 | #endif |
| 154 | if (need_to_dispatch && context_acquired) | 168 | if (need_to_dispatch) |
| 155 | { | 169 | { |
| 170 | acquire_select_lock (context); | ||
| 171 | |||
| 156 | int pselect_errno = errno; | 172 | int pselect_errno = errno; |
| 157 | /* Prevent g_main_dispatch recursion, that would occur without | 173 | /* Prevent g_main_dispatch recursion, that would occur without |
| 158 | block_input wrapper, because event handlers call | 174 | block_input wrapper, because event handlers call |
| @@ -162,11 +178,9 @@ xg_select (int fds_lim, fd_set *rfds, fd_set *wfds, fd_set *efds, | |||
| 162 | g_main_context_dispatch (context); | 178 | g_main_context_dispatch (context); |
| 163 | unblock_input (); | 179 | unblock_input (); |
| 164 | errno = pselect_errno; | 180 | errno = pselect_errno; |
| 181 | release_select_lock (); | ||
| 165 | } | 182 | } |
| 166 | 183 | ||
| 167 | if (context_acquired) | ||
| 168 | g_main_context_release (context); | ||
| 169 | |||
| 170 | /* To not have to recalculate timeout, return like this. */ | 184 | /* To not have to recalculate timeout, return like this. */ |
| 171 | if ((our_fds > 0 || (nfds == 0 && tmop == &tmo)) && (retval == 0)) | 185 | if ((our_fds > 0 || (nfds == 0 && tmop == &tmo)) && (retval == 0)) |
| 172 | { | 186 | { |
diff --git a/src/xgselect.h b/src/xgselect.h index a38591f3296..512bf3ad85f 100644 --- a/src/xgselect.h +++ b/src/xgselect.h | |||
| @@ -29,4 +29,6 @@ extern int xg_select (int max_fds, | |||
| 29 | fd_set *rfds, fd_set *wfds, fd_set *efds, | 29 | fd_set *rfds, fd_set *wfds, fd_set *efds, |
| 30 | struct timespec *timeout, sigset_t *sigmask); | 30 | struct timespec *timeout, sigset_t *sigmask); |
| 31 | 31 | ||
| 32 | extern void release_select_lock (void); | ||
| 33 | |||
| 32 | #endif /* XGSELECT_H */ | 34 | #endif /* XGSELECT_H */ |