aboutsummaryrefslogtreecommitdiffstats
path: root/src/mac.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mac.c')
-rw-r--r--src/mac.c463
1 files changed, 248 insertions, 215 deletions
diff --git a/src/mac.c b/src/mac.c
index 67fd5e4f5e0..be6953a0d55 100644
--- a/src/mac.c
+++ b/src/mac.c
@@ -2413,75 +2413,69 @@ sys_fopen (const char *name, const char *mode)
2413} 2413}
2414 2414
2415 2415
2416#include "keyboard.h" 2416extern Boolean mac_wait_next_event P_ ((EventRecord *, UInt32, Boolean));
2417extern Boolean mac_wait_next_event (EventRecord *, UInt32, Boolean);
2418 2417
2419int 2418int
2420select (n, rfds, wfds, efds, timeout) 2419select (nfds, rfds, wfds, efds, timeout)
2421 int n; 2420 int nfds;
2422 SELECT_TYPE *rfds; 2421 SELECT_TYPE *rfds, *wfds, *efds;
2423 SELECT_TYPE *wfds; 2422 EMACS_TIME *timeout;
2424 SELECT_TYPE *efds;
2425 struct timeval *timeout;
2426{ 2423{
2427 OSStatus err; 2424 OSStatus err = noErr;
2428#if TARGET_API_MAC_CARBON
2429 EventTimeout timeout_sec =
2430 (timeout
2431 ? (EMACS_SECS (*timeout) * kEventDurationSecond
2432 + EMACS_USECS (*timeout) * kEventDurationMicrosecond)
2433 : kEventDurationForever);
2434
2435 BLOCK_INPUT;
2436 err = ReceiveNextEvent (0, NULL, timeout_sec, kEventLeaveInQueue, NULL);
2437 UNBLOCK_INPUT;
2438#else /* not TARGET_API_MAC_CARBON */
2439 EventRecord e;
2440 UInt32 sleep_time = EMACS_SECS (*timeout) * 60 +
2441 ((EMACS_USECS (*timeout) * 60) / 1000000);
2442 2425
2443 /* Can only handle wait for keyboard input. */ 2426 /* Can only handle wait for keyboard input. */
2444 if (n > 1 || wfds || efds) 2427 if (nfds > 1 || wfds || efds)
2445 return -1; 2428 return -1;
2446 2429
2447 /* Also return true if an event other than a keyDown has occurred. 2430 /* Try detect_input_pending before ReceiveNextEvent in the same
2448 This causes kbd_buffer_get_event in keyboard.c to call 2431 BLOCK_INPUT block, in case that some input has already been read
2449 read_avail_input which in turn calls XTread_socket to poll for 2432 asynchronously. */
2450 these events. Otherwise these never get processed except but a 2433 BLOCK_INPUT;
2451 very slow poll timer. */ 2434 if (!detect_input_pending ())
2452 if (mac_wait_next_event (&e, sleep_time, false)) 2435 {
2453 err = noErr; 2436#if TARGET_API_MAC_CARBON
2454 else 2437 EventTimeout timeoutval =
2455 err = -9875; /* eventLoopTimedOutErr */ 2438 (timeout
2439 ? (EMACS_SECS (*timeout) * kEventDurationSecond
2440 + EMACS_USECS (*timeout) * kEventDurationMicrosecond)
2441 : kEventDurationForever);
2442
2443 if (timeoutval == 0.0)
2444 err = eventLoopTimedOutErr;
2445 else
2446 err = ReceiveNextEvent (0, NULL, timeoutval,
2447 kEventLeaveInQueue, NULL);
2448#else /* not TARGET_API_MAC_CARBON */
2449 EventRecord e;
2450 UInt32 sleep_time = EMACS_SECS (*timeout) * 60 +
2451 ((EMACS_USECS (*timeout) * 60) / 1000000);
2452
2453 if (sleep_time == 0)
2454 err = -9875; /* eventLoopTimedOutErr */
2455 else
2456 {
2457 if (mac_wait_next_event (&e, sleep_time, false))
2458 err = noErr;
2459 else
2460 err = -9875; /* eventLoopTimedOutErr */
2461 }
2456#endif /* not TARGET_API_MAC_CARBON */ 2462#endif /* not TARGET_API_MAC_CARBON */
2463 }
2464 UNBLOCK_INPUT;
2457 2465
2458 if (FD_ISSET (0, rfds)) 2466 if (err == noErr)
2459 if (err == noErr) 2467 {
2460 return 1; 2468 /* Pretend that `select' is interrupted by a signal. */
2461 else 2469 detect_input_pending ();
2462 { 2470 errno = EINTR;
2463 FD_ZERO (rfds); 2471 return -1;
2464 return 0; 2472 }
2465 }
2466 else 2473 else
2467 if (err == noErr) 2474 {
2468 { 2475 if (rfds)
2469 if (input_polling_used ()) 2476 FD_ZERO (rfds);
2470 {
2471 /* It could be confusing if a real alarm arrives while
2472 processing the fake one. Turn it off and let the
2473 handler reset it. */
2474 extern void poll_for_input_1 P_ ((void));
2475 int old_poll_suppress_count = poll_suppress_count;
2476 poll_suppress_count = 1;
2477 poll_for_input_1 ();
2478 poll_suppress_count = old_poll_suppress_count;
2479 }
2480 errno = EINTR;
2481 return -1;
2482 }
2483 else
2484 return 0; 2477 return 0;
2478 }
2485} 2479}
2486 2480
2487 2481
@@ -4904,6 +4898,30 @@ On successful conversion, return the result string, else return nil. */)
4904 4898
4905 return result; 4899 return result;
4906} 4900}
4901
4902DEFUN ("mac-process-hi-command", Fmac_process_hi_command, Smac_process_hi_command, 1, 1, 0,
4903 doc: /* Send a HI command whose ID is COMMAND-ID to the command chain.
4904COMMAND-ID must be a 4-character string. Some common command IDs are
4905defined in the Carbon Event Manager. */)
4906 (command_id)
4907 Lisp_Object command_id;
4908{
4909 OSStatus err;
4910 HICommand command;
4911
4912 bzero (&command, sizeof (HICommand));
4913 command.commandID = mac_get_code_from_arg (command_id, 0);
4914
4915 BLOCK_INPUT;
4916 err = ProcessHICommand (&command);
4917 UNBLOCK_INPUT;
4918
4919 if (err != noErr)
4920 error ("HI command (command ID: '%s') not handled.", SDATA (command_id));
4921
4922 return Qnil;
4923}
4924
4907#endif /* TARGET_API_MAC_CARBON */ 4925#endif /* TARGET_API_MAC_CARBON */
4908 4926
4909 4927
@@ -4944,23 +4962,26 @@ extern int noninteractive;
4944 -> Use `select'. 4962 -> Use `select'.
4945 2. Sockets are not involved. 4963 2. Sockets are not involved.
4946 -> Use ReceiveNextEvent. 4964 -> Use ReceiveNextEvent.
4947 3. [If SELECT_USE_CFSOCKET is defined] 4965 3. [If SELECT_USE_CFSOCKET is set]
4948 Only the window event channel and socket read channels are 4966 Only the window event channel and socket read/write channels are
4949 involved, and timeout is not too short (greater than 4967 involved, and timeout is not too short (greater than
4950 SELECT_TIMEOUT_THRESHHOLD_RUNLOOP seconds). 4968 SELECT_TIMEOUT_THRESHHOLD_RUNLOOP seconds).
4951 -> Create CFSocket for each socket and add it into the current 4969 -> Create CFSocket for each socket and add it into the current
4952 event RunLoop so that a `ready-to-read' event can be posted 4970 event RunLoop so that the current event loop gets quit when
4953 to the event queue that is also used for window events. Then 4971 the socket becomes ready. Then ReceiveNextEvent can wait for
4954 ReceiveNextEvent can wait for both kinds of inputs. 4972 both kinds of inputs.
4955 4. Otherwise. 4973 4. Otherwise.
4956 -> Periodically poll the window input channel while repeatedly 4974 -> Periodically poll the window input channel while repeatedly
4957 executing `select' with a short timeout 4975 executing `select' with a short timeout
4958 (SELECT_POLLING_PERIOD_USEC microseconds). */ 4976 (SELECT_POLLING_PERIOD_USEC microseconds). */
4959 4977
4960#define SELECT_POLLING_PERIOD_USEC 20000 4978#ifndef SELECT_USE_CFSOCKET
4961#ifdef SELECT_USE_CFSOCKET 4979#define SELECT_USE_CFSOCKET 1
4980#endif
4981
4982#define SELECT_POLLING_PERIOD_USEC 100000
4983#if SELECT_USE_CFSOCKET
4962#define SELECT_TIMEOUT_THRESHOLD_RUNLOOP 0.2 4984#define SELECT_TIMEOUT_THRESHOLD_RUNLOOP 0.2
4963#define EVENT_CLASS_SOCK 'Sock'
4964 4985
4965static void 4986static void
4966socket_callback (s, type, address, data, info) 4987socket_callback (s, type, address, data, info)
@@ -4970,196 +4991,211 @@ socket_callback (s, type, address, data, info)
4970 const void *data; 4991 const void *data;
4971 void *info; 4992 void *info;
4972{ 4993{
4973 EventRef event; 4994 int fd = CFSocketGetNative (s);
4995 SELECT_TYPE *ofds = (SELECT_TYPE *)info;
4974 4996
4975 CreateEvent (NULL, EVENT_CLASS_SOCK, 0, 0, kEventAttributeNone, &event); 4997 if ((type == kCFSocketReadCallBack && FD_ISSET (fd, &ofds[0]))
4976 PostEventToQueue (GetCurrentEventQueue (), event, kEventPriorityStandard); 4998 || (type == kCFSocketConnectCallBack && FD_ISSET (fd, &ofds[1])))
4977 ReleaseEvent (event); 4999 QuitEventLoop (GetCurrentEventLoop ());
4978} 5000}
4979#endif /* SELECT_USE_CFSOCKET */ 5001#endif /* SELECT_USE_CFSOCKET */
4980 5002
4981static int 5003static int
4982select_and_poll_event (n, rfds, wfds, efds, timeout) 5004select_and_poll_event (nfds, rfds, wfds, efds, timeout)
4983 int n; 5005 int nfds;
4984 SELECT_TYPE *rfds; 5006 SELECT_TYPE *rfds, *wfds, *efds;
4985 SELECT_TYPE *wfds; 5007 EMACS_TIME *timeout;
4986 SELECT_TYPE *efds;
4987 struct timeval *timeout;
4988{ 5008{
4989 int r; 5009 OSStatus err = noErr;
4990 OSStatus err; 5010 int r = 0;
4991 5011
4992 r = select (n, rfds, wfds, efds, timeout); 5012 /* Try detect_input_pending before ReceiveNextEvent in the same
4993 if (r != -1) 5013 BLOCK_INPUT block, in case that some input has already been read
5014 asynchronously. */
5015 BLOCK_INPUT;
5016 if (!detect_input_pending ())
4994 { 5017 {
4995 BLOCK_INPUT; 5018 EMACS_TIME select_timeout;
4996 err = ReceiveNextEvent (0, NULL, kEventDurationNoWait, 5019 EventTimeout timeoutval =
4997 kEventLeaveInQueue, NULL); 5020 (timeout
4998 UNBLOCK_INPUT; 5021 ? (EMACS_SECS (*timeout) * kEventDurationSecond
4999 if (err == noErr) 5022 + EMACS_USECS (*timeout) * kEventDurationMicrosecond)
5023 : kEventDurationForever);
5024
5025 EMACS_SET_SECS_USECS (select_timeout, 0, 0);
5026 r = select (nfds, rfds, wfds, efds, &select_timeout);
5027 if (timeoutval == 0.0)
5028 err = eventLoopTimedOutErr;
5029 else if (r == 0)
5000 { 5030 {
5001 FD_SET (0, rfds); 5031#if USE_CG_DRAWING
5002 r++; 5032 mac_prepare_for_quickdraw (NULL);
5033#endif
5034 err = ReceiveNextEvent (0, NULL, timeoutval,
5035 kEventLeaveInQueue, NULL);
5003 } 5036 }
5004 } 5037 }
5005 return r; 5038 UNBLOCK_INPUT;
5006}
5007 5039
5008#if MAC_OS_X_VERSION_MAX_ALLOWED < 1020 5040 if (r != 0)
5009#undef SELECT_INVALIDATE_CFSOCKET 5041 return r;
5010#endif 5042 else if (err == noErr)
5043 {
5044 /* Pretend that `select' is interrupted by a signal. */
5045 detect_input_pending ();
5046 errno = EINTR;
5047 return -1;
5048 }
5049 else
5050 return 0;
5051}
5011 5052
5012int 5053int
5013sys_select (n, rfds, wfds, efds, timeout) 5054sys_select (nfds, rfds, wfds, efds, timeout)
5014 int n; 5055 int nfds;
5015 SELECT_TYPE *rfds; 5056 SELECT_TYPE *rfds, *wfds, *efds;
5016 SELECT_TYPE *wfds; 5057 EMACS_TIME *timeout;
5017 SELECT_TYPE *efds;
5018 struct timeval *timeout;
5019{ 5058{
5020 OSStatus err; 5059 OSStatus err = noErr;
5021 int i, r; 5060 int r;
5022 EMACS_TIME select_timeout; 5061 EMACS_TIME select_timeout;
5062 static SELECT_TYPE ofds[3];
5023 5063
5024 if (inhibit_window_system || noninteractive 5064 if (inhibit_window_system || noninteractive
5025 || rfds == NULL || !FD_ISSET (0, rfds)) 5065 || nfds < 1 || rfds == NULL || !FD_ISSET (0, rfds))
5026 return select (n, rfds, wfds, efds, timeout); 5066 return select (nfds, rfds, wfds, efds, timeout);
5027 5067
5028 FD_CLR (0, rfds); 5068 FD_CLR (0, rfds);
5069 ofds[0] = *rfds;
5029 5070
5030 if (wfds == NULL && efds == NULL) 5071 if (wfds)
5031 { 5072 ofds[1] = *wfds;
5032 int nsocks = 0; 5073 else
5033 SELECT_TYPE orfds = *rfds; 5074 FD_ZERO (&ofds[1]);
5034 5075
5035 EventTimeout timeout_sec = 5076 if (efds)
5077 ofds[2] = *efds;
5078 else
5079 {
5080 EventTimeout timeoutval =
5036 (timeout 5081 (timeout
5037 ? (EMACS_SECS (*timeout) * kEventDurationSecond 5082 ? (EMACS_SECS (*timeout) * kEventDurationSecond
5038 + EMACS_USECS (*timeout) * kEventDurationMicrosecond) 5083 + EMACS_USECS (*timeout) * kEventDurationMicrosecond)
5039 : kEventDurationForever); 5084 : kEventDurationForever);
5040 5085
5041 for (i = 1; i < n; i++) 5086 FD_SET (0, rfds); /* sentinel */
5042 if (FD_ISSET (i, rfds)) 5087 do
5043 nsocks++;
5044
5045 if (nsocks == 0)
5046 { 5088 {
5047 BLOCK_INPUT; 5089 nfds--;
5048 err = ReceiveNextEvent (0, NULL, timeout_sec,
5049 kEventLeaveInQueue, NULL);
5050 UNBLOCK_INPUT;
5051 if (err == noErr)
5052 {
5053 FD_SET (0, rfds);
5054 return 1;
5055 }
5056 else
5057 return 0;
5058 } 5090 }
5091 while (!(FD_ISSET (nfds, rfds) || (wfds && FD_ISSET (nfds, wfds))));
5092 nfds++;
5093 FD_CLR (0, rfds);
5094
5095 if (nfds == 1)
5096 return select_and_poll_event (nfds, rfds, wfds, efds, timeout);
5059 5097
5060#if USE_CG_DRAWING
5061 mac_prepare_for_quickdraw (NULL);
5062#endif
5063 /* Avoid initial overhead of RunLoop setup for the case that 5098 /* Avoid initial overhead of RunLoop setup for the case that
5064 some input is already available. */ 5099 some input is already available. */
5065 EMACS_SET_SECS_USECS (select_timeout, 0, 0); 5100 EMACS_SET_SECS_USECS (select_timeout, 0, 0);
5066 r = select_and_poll_event (n, rfds, wfds, efds, &select_timeout); 5101 r = select_and_poll_event (nfds, rfds, wfds, efds, &select_timeout);
5067 if (r != 0 || timeout_sec == 0.0) 5102 if (r != 0 || timeoutval == 0.0)
5068 return r; 5103 return r;
5069 5104
5070 *rfds = orfds; 5105 *rfds = ofds[0];
5106 if (wfds)
5107 *wfds = ofds[1];
5071 5108
5072#ifdef SELECT_USE_CFSOCKET 5109#if SELECT_USE_CFSOCKET
5073 if (timeout_sec > 0 && timeout_sec <= SELECT_TIMEOUT_THRESHOLD_RUNLOOP) 5110 if (timeoutval > 0 && timeoutval <= SELECT_TIMEOUT_THRESHOLD_RUNLOOP)
5074 goto poll_periodically; 5111 goto poll_periodically;
5075 5112
5076 { 5113 /* Try detect_input_pending before ReceiveNextEvent in the same
5077 CFRunLoopRef runloop = 5114 BLOCK_INPUT block, in case that some input has already been
5078 (CFRunLoopRef) GetCFRunLoopFromEventLoop (GetCurrentEventLoop ()); 5115 read asynchronously. */
5079 EventTypeSpec specs[] = {{EVENT_CLASS_SOCK, 0}}; 5116 BLOCK_INPUT;
5080#ifdef SELECT_INVALIDATE_CFSOCKET 5117 if (!detect_input_pending ())
5081 CFSocketRef *shead, *s; 5118 {
5082#else 5119 int minfd, fd;
5083 CFRunLoopSourceRef *shead, *s; 5120 CFRunLoopRef runloop =
5084#endif 5121 (CFRunLoopRef) GetCFRunLoopFromEventLoop (GetCurrentEventLoop ());
5085 5122 static CFSocketContext context = {0, ofds, NULL, NULL, NULL};
5086 BLOCK_INPUT; 5123 static CFMutableDictionaryRef sources;
5087 5124
5088#ifdef SELECT_INVALIDATE_CFSOCKET 5125 if (sources == NULL)
5089 shead = xmalloc (sizeof (CFSocketRef) * nsocks); 5126 sources =
5090#else 5127 CFDictionaryCreateMutable (NULL, 0, NULL,
5091 shead = xmalloc (sizeof (CFRunLoopSourceRef) * nsocks); 5128 &kCFTypeDictionaryValueCallBacks);
5092#endif 5129
5093 s = shead; 5130 for (minfd = 1; ; minfd++) /* nfds-1 works as a sentinel. */
5094 for (i = 1; i < n; i++) 5131 if (FD_ISSET (minfd, rfds) || (wfds && FD_ISSET (minfd, wfds)))
5095 if (FD_ISSET (i, rfds)) 5132 break;
5096 {
5097 CFSocketRef socket =
5098 CFSocketCreateWithNative (NULL, i, kCFSocketReadCallBack,
5099 socket_callback, NULL);
5100 CFRunLoopSourceRef source =
5101 CFSocketCreateRunLoopSource (NULL, socket, 0);
5102
5103#ifdef SELECT_INVALIDATE_CFSOCKET
5104 CFSocketSetSocketFlags (socket, 0);
5105#endif
5106 CFRunLoopAddSource (runloop, source, kCFRunLoopDefaultMode);
5107#ifdef SELECT_INVALIDATE_CFSOCKET
5108 CFRelease (source);
5109 *s = socket;
5110#else
5111 CFRelease (socket);
5112 *s = source;
5113#endif
5114 s++;
5115 }
5116 5133
5117 err = ReceiveNextEvent (0, NULL, timeout_sec, kEventLeaveInQueue, NULL); 5134 for (fd = minfd; fd < nfds; fd++)
5135 if (FD_ISSET (fd, rfds) || (wfds && FD_ISSET (fd, wfds)))
5136 {
5137 void *key = (void *) fd;
5138 CFRunLoopSourceRef source =
5139 (CFRunLoopSourceRef) CFDictionaryGetValue (sources, key);
5140
5141 if (source == NULL)
5142 {
5143 CFSocketRef socket =
5144 CFSocketCreateWithNative (NULL, fd,
5145 (kCFSocketReadCallBack
5146 | kCFSocketConnectCallBack),
5147 socket_callback, &context);
5148
5149 if (socket == NULL)
5150 continue;
5151 source = CFSocketCreateRunLoopSource (NULL, socket, 0);
5152 CFRelease (socket);
5153 if (source == NULL)
5154 continue;
5155 CFDictionaryAddValue (sources, key, source);
5156 CFRelease (source);
5157 }
5158 CFRunLoopAddSource (runloop, source, kCFRunLoopDefaultMode);
5159 }
5118 5160
5119 do 5161#if USE_CG_DRAWING
5120 { 5162 mac_prepare_for_quickdraw (NULL);
5121 --s;
5122#ifdef SELECT_INVALIDATE_CFSOCKET
5123 CFSocketInvalidate (*s);
5124#else
5125 CFRunLoopRemoveSource (runloop, *s, kCFRunLoopDefaultMode);
5126#endif 5163#endif
5127 CFRelease (*s); 5164 err = ReceiveNextEvent (0, NULL, timeoutval,
5128 } 5165 kEventLeaveInQueue, NULL);
5129 while (s != shead);
5130
5131 xfree (shead);
5132 5166
5133 if (err) 5167 for (fd = minfd; fd < nfds; fd++)
5134 { 5168 if (FD_ISSET (fd, rfds) || (wfds && FD_ISSET (fd, wfds)))
5135 FD_ZERO (rfds); 5169 {
5136 r = 0; 5170 void *key = (void *) fd;
5137 } 5171 CFRunLoopSourceRef source =
5138 else 5172 (CFRunLoopSourceRef) CFDictionaryGetValue (sources, key);
5139 {
5140 FlushEventsMatchingListFromQueue (GetCurrentEventQueue (),
5141 GetEventTypeCount (specs),
5142 specs);
5143 EMACS_SET_SECS_USECS (select_timeout, 0, 0);
5144 r = select_and_poll_event (n, rfds, wfds, efds, &select_timeout);
5145 }
5146 5173
5147 UNBLOCK_INPUT; 5174 CFRunLoopRemoveSource (runloop, source, kCFRunLoopDefaultMode);
5175 }
5176 }
5177 UNBLOCK_INPUT;
5148 5178
5149 return r; 5179 if (err == noErr || err == eventLoopQuitErr)
5150 } 5180 {
5181 EMACS_SET_SECS_USECS (select_timeout, 0, 0);
5182 return select_and_poll_event (nfds, rfds, wfds, efds,
5183 &select_timeout);
5184 }
5185 else
5186 {
5187 FD_ZERO (rfds);
5188 if (wfds)
5189 FD_ZERO (wfds);
5190 return 0;
5191 }
5151#endif /* SELECT_USE_CFSOCKET */ 5192#endif /* SELECT_USE_CFSOCKET */
5152 } 5193 }
5153 5194
5154 poll_periodically: 5195 poll_periodically:
5155 { 5196 {
5156 EMACS_TIME end_time, now, remaining_time; 5197 EMACS_TIME end_time, now, remaining_time;
5157 SELECT_TYPE orfds = *rfds, owfds, oefds;
5158 5198
5159 if (wfds)
5160 owfds = *wfds;
5161 if (efds)
5162 oefds = *efds;
5163 if (timeout) 5199 if (timeout)
5164 { 5200 {
5165 remaining_time = *timeout; 5201 remaining_time = *timeout;
@@ -5172,15 +5208,15 @@ sys_select (n, rfds, wfds, efds, timeout)
5172 EMACS_SET_SECS_USECS (select_timeout, 0, SELECT_POLLING_PERIOD_USEC); 5208 EMACS_SET_SECS_USECS (select_timeout, 0, SELECT_POLLING_PERIOD_USEC);
5173 if (timeout && EMACS_TIME_LT (remaining_time, select_timeout)) 5209 if (timeout && EMACS_TIME_LT (remaining_time, select_timeout))
5174 select_timeout = remaining_time; 5210 select_timeout = remaining_time;
5175 r = select_and_poll_event (n, rfds, wfds, efds, &select_timeout); 5211 r = select_and_poll_event (nfds, rfds, wfds, efds, &select_timeout);
5176 if (r != 0) 5212 if (r != 0)
5177 return r; 5213 return r;
5178 5214
5179 *rfds = orfds; 5215 *rfds = ofds[0];
5180 if (wfds) 5216 if (wfds)
5181 *wfds = owfds; 5217 *wfds = ofds[1];
5182 if (efds) 5218 if (efds)
5183 *efds = oefds; 5219 *efds = ofds[2];
5184 5220
5185 if (timeout) 5221 if (timeout)
5186 { 5222 {
@@ -5190,12 +5226,8 @@ sys_select (n, rfds, wfds, efds, timeout)
5190 } 5226 }
5191 while (!timeout || EMACS_TIME_LT (now, end_time)); 5227 while (!timeout || EMACS_TIME_LT (now, end_time));
5192 5228
5193 FD_ZERO (rfds); 5229 EMACS_SET_SECS_USECS (select_timeout, 0, 0);
5194 if (wfds) 5230 return select_and_poll_event (nfds, rfds, wfds, efds, &select_timeout);
5195 FD_ZERO (wfds);
5196 if (efds)
5197 FD_ZERO (efds);
5198 return 0;
5199 } 5231 }
5200} 5232}
5201 5233
@@ -5387,6 +5419,7 @@ syms_of_mac ()
5387#if TARGET_API_MAC_CARBON 5419#if TARGET_API_MAC_CARBON
5388 defsubr (&Smac_get_preference); 5420 defsubr (&Smac_get_preference);
5389 defsubr (&Smac_code_convert_string); 5421 defsubr (&Smac_code_convert_string);
5422 defsubr (&Smac_process_hi_command);
5390#endif 5423#endif
5391 5424
5392 defsubr (&Smac_set_file_creator); 5425 defsubr (&Smac_set_file_creator);