aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrea Corallo2020-08-23 11:52:18 +0200
committerAndrea Corallo2020-08-23 11:52:18 +0200
commitfafc9c21175ee50df84114a09e9f43f02c960b85 (patch)
treebd07feaed951d7bd49ed53d65bb2e6082a6c1196 /src
parentc818c29771d3cb51875643b2f6c894073e429dd2 (diff)
parent4e97019a77731d634e6b059954c8fef792c11fa8 (diff)
downloademacs-fafc9c21175ee50df84114a09e9f43f02c960b85.tar.gz
emacs-fafc9c21175ee50df84114a09e9f43f02c960b85.zip
Merge remote-tracking branch 'savannah/master' into HEAD
Diffstat (limited to 'src')
-rw-r--r--src/callproc.c6
-rw-r--r--src/ccl.c2
-rw-r--r--src/editfns.c3
-rw-r--r--src/image.c2
-rw-r--r--src/minibuf.c2
-rw-r--r--src/nsfns.m139
-rw-r--r--src/nsterm.h6
-rw-r--r--src/nsterm.m25
-rw-r--r--src/process.c5
-rw-r--r--src/thread.c8
-rw-r--r--src/xdisp.c189
-rw-r--r--src/xgselect.c42
-rw-r--r--src/xgselect.h2
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,
231Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted. 231Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted.
232Remaining arguments ARGS are strings passed as command arguments to PROGRAM. 232Remaining arguments ARGS are strings passed as command arguments to PROGRAM.
233 233
234If PROGRAM is not an absolute file name, `call-process' will look for
235PROGRAM in `exec-path' (which is a list of directories).
236
234If executable PROGRAM can't be found as an executable, `call-process' 237If executable PROGRAM can't be found as an executable, `call-process'
235signals a Lisp error. `call-process' reports errors in execution of 238signals a Lisp error. `call-process' reports errors in execution of
236the program only through its return and output. 239the program only through its return and output.
@@ -1060,6 +1063,9 @@ Sixth arg DISPLAY non-nil means redisplay buffer as output is inserted.
1060Remaining arguments ARGS are passed to PROGRAM at startup as command-line 1063Remaining arguments ARGS are passed to PROGRAM at startup as command-line
1061arguments. 1064arguments.
1062 1065
1066If PROGRAM is not an absolute file name, `call-process-region' will
1067look for PROGRAM in `exec-path' (which is a list of directories).
1068
1063If BUFFER is 0, `call-process-region' returns immediately with value nil. 1069If BUFFER is 0, `call-process-region' returns immediately with value nil.
1064Otherwise it waits for PROGRAM to terminate 1070Otherwise it waits for PROGRAM to terminate
1065and returns a numeric exit status or a signal description string. 1071and returns a numeric exit status or a signal description string.
diff --git a/src/ccl.c b/src/ccl.c
index 86debeef0e5..796698eb1ce 100644
--- a/src/ccl.c
+++ b/src/ccl.c
@@ -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
708This function ignores text display directionality; it returns the 708This function ignores text display directionality; it returns the
709position of the first character in logical order, i.e. the smallest 709position of the first character in logical order, i.e. the smallest
710character position on the line. 710character position on the logical line. See `vertical-motion' for
711movement by screen lines.
711 712
712This function constrains the returned position to the current field 713This function constrains the returned position to the current field
713unless that position would be on a different line from the original, 714unless 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. */)
1039DEFUN ("read-variable", Fread_variable, Sread_variable, 1, 2, 0, 1039DEFUN ("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.
1041Prompt with PROMPT. By default, return DEFAULT-VALUE or its first element 1041Prompt with PROMPT. By default, return DEFAULT-VALUE or its first element
1042if it is a list. 1042if it is a list of strings.
1043A user option, or customizable variable, is one for which 1043A 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
401static void 400static void
402ns_set_name_internal (struct frame *f, Lisp_Object name) 401ns_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)
851static Lisp_Object 837static Lisp_Object
852ns_appkit_version_str (void) 838ns_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. */
3016static bool
3017all_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
1654also nil, meaning that this process is not associated with any buffer. 1654also 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
1657name, followed by strings to give to the program as arguments. 1657name, followed by strings to give to the program as arguments. If the
1658program file name is not an absolute file name, `make-process' will
1659look for the program file name in `exec-path' (which is a list of
1660directories).
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
1660system used for both reading and writing for this process. If CODING 1663system 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
31union aligned_thread_state 37union 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
518static bool
519it_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. */
538static bool
539char_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. */
560static bool
561char_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'.
34662If `word-wrap' is enabled, you might want to reduce this. */); 34758If `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.
34763Normally when `word-wrap' is on, Emacs only breaks lines after
34764whitespace characters. When this option is turned on, Emacs also
34765breaks lines after characters that have the "|" category (defined in
34766characters.el). This is useful for allowing breaking after CJK
34767characters and improves the word-wrapping for CJK text mixed with
34768Latin text.
34769
34770If this variable is set using Customize, Emacs automatically loads
34771kinsoku.el. When kinsoku.el is loaded, Emacs respects kinsoku rules
34772when breaking lines. That means characters with the ">" category
34773don't appear at the beginning of a line (e.g., FULLWIDTH COMMA), and
34774characters 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.
34667If the buffer is bigger than this, the line number does not appear 34780If 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
32static ptrdiff_t threads_holding_glib_lock;
33static GMainContext *glib_main_context;
34
35void release_select_lock (void)
36{
37 if (--threads_holding_glib_lock == 0)
38 g_main_context_release (glib_main_context);
39}
40
41static 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
32extern void release_select_lock (void);
33
32#endif /* XGSELECT_H */ 34#endif /* XGSELECT_H */