comparison src/mac.c @ 83542:2d56e13fd23d

Merged from emacs@sv.gnu.org Patches applied: * emacs@sv.gnu.org/emacs--devo--0--patch-413 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-414 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-415 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-416 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-417 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-418 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-419 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-420 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-421 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-422 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-423 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-424 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-425 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-426 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-427 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-428 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-429 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-430 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-431 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-432 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-433 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-434 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-435 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-436 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-437 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-438 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-439 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-440 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-441 lisp/url/url-methods.el: Fix format error when http_proxy is empty string * emacs@sv.gnu.org/emacs--devo--0--patch-442 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-443 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-444 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-445 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-446 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-447 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-448 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-449 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-450 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-451 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-452 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-453 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-454 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-455 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-456 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-457 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-458 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-459 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-460 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-461 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-462 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-463 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-464 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-465 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-466 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-467 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-468 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-469 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-470 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-471 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-472 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-473 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-128 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-129 Merge from emacs--devo--0 * emacs@sv.gnu.org/gnus--rel--5.10--patch-130 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-131 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-132 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-133 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-134 Merge from emacs--devo--0 * emacs@sv.gnu.org/gnus--rel--5.10--patch-135 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-136 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-137 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-138 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-139 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-140 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-141 Merge from emacs--devo--0 * emacs@sv.gnu.org/gnus--rel--5.10--patch-142 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-143 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-144 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-145 Merge from emacs--devo--0 * emacs@sv.gnu.org/gnus--rel--5.10--patch-146 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-147 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-148 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-149 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-582
author Karoly Lorentey <lorentey@elte.hu>
date Sat, 14 Oct 2006 17:36:28 +0000
parents ddc3ec9e715f
children c5a4a949a307 b5c13d1564a9
comparison
equal deleted inserted replaced
83541:694bbb62a75d 83542:2d56e13fd23d
2411 return fopen (mac_pathname, mode); 2411 return fopen (mac_pathname, mode);
2412 } 2412 }
2413 } 2413 }
2414 2414
2415 2415
2416 #include "keyboard.h" 2416 extern Boolean mac_wait_next_event P_ ((EventRecord *, UInt32, Boolean));
2417 extern Boolean mac_wait_next_event (EventRecord *, UInt32, Boolean);
2418 2417
2419 int 2418 int
2420 select (n, rfds, wfds, efds, timeout) 2419 select (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; 2423 {
2425 struct timeval *timeout; 2424 OSStatus err = noErr;
2426 { 2425
2427 OSStatus err; 2426 /* Can only handle wait for keyboard input. */
2427 if (nfds > 1 || wfds || efds)
2428 return -1;
2429
2430 /* Try detect_input_pending before ReceiveNextEvent in the same
2431 BLOCK_INPUT block, in case that some input has already been read
2432 asynchronously. */
2433 BLOCK_INPUT;
2434 if (!detect_input_pending ())
2435 {
2428 #if TARGET_API_MAC_CARBON 2436 #if TARGET_API_MAC_CARBON
2429 EventTimeout timeout_sec = 2437 EventTimeout timeoutval =
2430 (timeout 2438 (timeout
2431 ? (EMACS_SECS (*timeout) * kEventDurationSecond 2439 ? (EMACS_SECS (*timeout) * kEventDurationSecond
2432 + EMACS_USECS (*timeout) * kEventDurationMicrosecond) 2440 + EMACS_USECS (*timeout) * kEventDurationMicrosecond)
2433 : kEventDurationForever); 2441 : kEventDurationForever);
2434 2442
2435 BLOCK_INPUT; 2443 if (timeoutval == 0.0)
2436 err = ReceiveNextEvent (0, NULL, timeout_sec, kEventLeaveInQueue, NULL); 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 }
2462 #endif /* not TARGET_API_MAC_CARBON */
2463 }
2437 UNBLOCK_INPUT; 2464 UNBLOCK_INPUT;
2438 #else /* not TARGET_API_MAC_CARBON */ 2465
2439 EventRecord e; 2466 if (err == noErr)
2440 UInt32 sleep_time = EMACS_SECS (*timeout) * 60 + 2467 {
2441 ((EMACS_USECS (*timeout) * 60) / 1000000); 2468 /* Pretend that `select' is interrupted by a signal. */
2442 2469 detect_input_pending ();
2443 /* Can only handle wait for keyboard input. */ 2470 errno = EINTR;
2444 if (n > 1 || wfds || efds) 2471 return -1;
2445 return -1; 2472 }
2446 2473 else
2447 /* Also return true if an event other than a keyDown has occurred. 2474 {
2448 This causes kbd_buffer_get_event in keyboard.c to call 2475 if (rfds)
2449 read_avail_input which in turn calls XTread_socket to poll for
2450 these events. Otherwise these never get processed except but a
2451 very slow poll timer. */
2452 if (mac_wait_next_event (&e, sleep_time, false))
2453 err = noErr;
2454 else
2455 err = -9875; /* eventLoopTimedOutErr */
2456 #endif /* not TARGET_API_MAC_CARBON */
2457
2458 if (FD_ISSET (0, rfds))
2459 if (err == noErr)
2460 return 1;
2461 else
2462 {
2463 FD_ZERO (rfds); 2476 FD_ZERO (rfds);
2464 return 0;
2465 }
2466 else
2467 if (err == noErr)
2468 {
2469 if (input_polling_used ())
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
2488 /* Simulation of SIGALRM. The stub for function signal stores the 2482 /* Simulation of SIGALRM. The stub for function signal stores the
2489 signal handler function in alarm_signal_func if a SIGALRM is 2483 signal handler function in alarm_signal_func if a SIGALRM is
4902 4896
4903 UNBLOCK_INPUT; 4897 UNBLOCK_INPUT;
4904 4898
4905 return result; 4899 return result;
4906 } 4900 }
4901
4902 DEFUN ("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.
4904 COMMAND-ID must be a 4-character string. Some common command IDs are
4905 defined 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
4910 static Lisp_Object 4928 static Lisp_Object
4911 mac_get_system_locale () 4929 mac_get_system_locale ()
4942 dividing into some cases: 4960 dividing into some cases:
4943 1. The window event channel is not involved. 4961 1. The window event channel is not involved.
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
4965 static void 4986 static void
4966 socket_callback (s, type, address, data, info) 4987 socket_callback (s, type, address, data, info)
4967 CFSocketRef s; 4988 CFSocketRef s;
4968 CFSocketCallBackType type; 4989 CFSocketCallBackType type;
4969 CFDataRef address; 4990 CFDataRef address;
4970 const void *data; 4991 const void *data;
4971 void *info; 4992 void *info;
4972 { 4993 {
4973 EventRef event; 4994 int fd = CFSocketGetNative (s);
4974 4995 SELECT_TYPE *ofds = (SELECT_TYPE *)info;
4975 CreateEvent (NULL, EVENT_CLASS_SOCK, 0, 0, kEventAttributeNone, &event); 4996
4976 PostEventToQueue (GetCurrentEventQueue (), event, kEventPriorityStandard); 4997 if ((type == kCFSocketReadCallBack && FD_ISSET (fd, &ofds[0]))
4977 ReleaseEvent (event); 4998 || (type == kCFSocketConnectCallBack && FD_ISSET (fd, &ofds[1])))
4999 QuitEventLoop (GetCurrentEventLoop ());
4978 } 5000 }
4979 #endif /* SELECT_USE_CFSOCKET */ 5001 #endif /* SELECT_USE_CFSOCKET */
4980 5002
4981 static int 5003 static int
4982 select_and_poll_event (n, rfds, wfds, efds, timeout) 5004 select_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; 5008 {
4987 struct timeval *timeout; 5009 OSStatus err = noErr;
4988 { 5010 int r = 0;
4989 int r; 5011
4990 OSStatus err; 5012 /* Try detect_input_pending before ReceiveNextEvent in the same
4991 5013 BLOCK_INPUT block, in case that some input has already been read
4992 r = select (n, rfds, wfds, efds, timeout); 5014 asynchronously. */
4993 if (r != -1) 5015 BLOCK_INPUT;
4994 { 5016 if (!detect_input_pending ())
4995 BLOCK_INPUT; 5017 {
4996 err = ReceiveNextEvent (0, NULL, kEventDurationNoWait, 5018 EMACS_TIME select_timeout;
4997 kEventLeaveInQueue, NULL); 5019 EventTimeout timeoutval =
4998 UNBLOCK_INPUT;
4999 if (err == noErr)
5000 {
5001 FD_SET (0, rfds);
5002 r++;
5003 }
5004 }
5005 return r;
5006 }
5007
5008 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1020
5009 #undef SELECT_INVALIDATE_CFSOCKET
5010 #endif
5011
5012 int
5013 sys_select (n, rfds, wfds, efds, timeout)
5014 int n;
5015 SELECT_TYPE *rfds;
5016 SELECT_TYPE *wfds;
5017 SELECT_TYPE *efds;
5018 struct timeval *timeout;
5019 {
5020 OSStatus err;
5021 int i, r;
5022 EMACS_TIME select_timeout;
5023
5024 if (inhibit_window_system || noninteractive
5025 || rfds == NULL || !FD_ISSET (0, rfds))
5026 return select (n, rfds, wfds, efds, timeout);
5027
5028 FD_CLR (0, rfds);
5029
5030 if (wfds == NULL && efds == NULL)
5031 {
5032 int nsocks = 0;
5033 SELECT_TYPE orfds = *rfds;
5034
5035 EventTimeout timeout_sec =
5036 (timeout 5020 (timeout
5037 ? (EMACS_SECS (*timeout) * kEventDurationSecond 5021 ? (EMACS_SECS (*timeout) * kEventDurationSecond
5038 + EMACS_USECS (*timeout) * kEventDurationMicrosecond) 5022 + EMACS_USECS (*timeout) * kEventDurationMicrosecond)
5039 : kEventDurationForever); 5023 : kEventDurationForever);
5040 5024
5041 for (i = 1; i < n; i++) 5025 EMACS_SET_SECS_USECS (select_timeout, 0, 0);
5042 if (FD_ISSET (i, rfds)) 5026 r = select (nfds, rfds, wfds, efds, &select_timeout);
5043 nsocks++; 5027 if (timeoutval == 0.0)
5044 5028 err = eventLoopTimedOutErr;
5045 if (nsocks == 0) 5029 else if (r == 0)
5046 { 5030 {
5047 BLOCK_INPUT; 5031 #if USE_CG_DRAWING
5048 err = ReceiveNextEvent (0, NULL, timeout_sec, 5032 mac_prepare_for_quickdraw (NULL);
5033 #endif
5034 err = ReceiveNextEvent (0, NULL, timeoutval,
5049 kEventLeaveInQueue, NULL); 5035 kEventLeaveInQueue, NULL);
5050 UNBLOCK_INPUT; 5036 }
5051 if (err == noErr) 5037 }
5052 { 5038 UNBLOCK_INPUT;
5053 FD_SET (0, rfds); 5039
5054 return 1; 5040 if (r != 0)
5055 } 5041 return r;
5056 else 5042 else if (err == noErr)
5057 return 0; 5043 {
5058 } 5044 /* Pretend that `select' is interrupted by a signal. */
5059 5045 detect_input_pending ();
5060 #if USE_CG_DRAWING 5046 errno = EINTR;
5061 mac_prepare_for_quickdraw (NULL); 5047 return -1;
5062 #endif 5048 }
5049 else
5050 return 0;
5051 }
5052
5053 int
5054 sys_select (nfds, rfds, wfds, efds, timeout)
5055 int nfds;
5056 SELECT_TYPE *rfds, *wfds, *efds;
5057 EMACS_TIME *timeout;
5058 {
5059 OSStatus err = noErr;
5060 int r;
5061 EMACS_TIME select_timeout;
5062 static SELECT_TYPE ofds[3];
5063
5064 if (inhibit_window_system || noninteractive
5065 || nfds < 1 || rfds == NULL || !FD_ISSET (0, rfds))
5066 return select (nfds, rfds, wfds, efds, timeout);
5067
5068 FD_CLR (0, rfds);
5069 ofds[0] = *rfds;
5070
5071 if (wfds)
5072 ofds[1] = *wfds;
5073 else
5074 FD_ZERO (&ofds[1]);
5075
5076 if (efds)
5077 ofds[2] = *efds;
5078 else
5079 {
5080 EventTimeout timeoutval =
5081 (timeout
5082 ? (EMACS_SECS (*timeout) * kEventDurationSecond
5083 + EMACS_USECS (*timeout) * kEventDurationMicrosecond)
5084 : kEventDurationForever);
5085
5086 FD_SET (0, rfds); /* sentinel */
5087 do
5088 {
5089 nfds--;
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);
5097
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];
5071 5106 if (wfds)
5072 #ifdef SELECT_USE_CFSOCKET 5107 *wfds = ofds[1];
5073 if (timeout_sec > 0 && timeout_sec <= SELECT_TIMEOUT_THRESHOLD_RUNLOOP) 5108
5109 #if SELECT_USE_CFSOCKET
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 =
5121 (CFRunLoopRef) GetCFRunLoopFromEventLoop (GetCurrentEventLoop ());
5122 static CFSocketContext context = {0, ofds, NULL, NULL, NULL};
5123 static CFMutableDictionaryRef sources;
5124
5125 if (sources == NULL)
5126 sources =
5127 CFDictionaryCreateMutable (NULL, 0, NULL,
5128 &kCFTypeDictionaryValueCallBacks);
5129
5130 for (minfd = 1; ; minfd++) /* nfds-1 works as a sentinel. */
5131 if (FD_ISSET (minfd, rfds) || (wfds && FD_ISSET (minfd, wfds)))
5132 break;
5133
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 }
5160
5161 #if USE_CG_DRAWING
5162 mac_prepare_for_quickdraw (NULL);
5084 #endif 5163 #endif
5085 5164 err = ReceiveNextEvent (0, NULL, timeoutval,
5086 BLOCK_INPUT; 5165 kEventLeaveInQueue, NULL);
5087 5166
5088 #ifdef SELECT_INVALIDATE_CFSOCKET 5167 for (fd = minfd; fd < nfds; fd++)
5089 shead = xmalloc (sizeof (CFSocketRef) * nsocks); 5168 if (FD_ISSET (fd, rfds) || (wfds && FD_ISSET (fd, wfds)))
5090 #else 5169 {
5091 shead = xmalloc (sizeof (CFRunLoopSourceRef) * nsocks); 5170 void *key = (void *) fd;
5092 #endif 5171 CFRunLoopSourceRef source =
5093 s = shead; 5172 (CFRunLoopSourceRef) CFDictionaryGetValue (sources, key);
5094 for (i = 1; i < n; i++) 5173
5095 if (FD_ISSET (i, rfds)) 5174 CFRunLoopRemoveSource (runloop, source, kCFRunLoopDefaultMode);
5096 { 5175 }
5097 CFSocketRef socket = 5176 }
5098 CFSocketCreateWithNative (NULL, i, kCFSocketReadCallBack, 5177 UNBLOCK_INPUT;
5099 socket_callback, NULL); 5178
5100 CFRunLoopSourceRef source = 5179 if (err == noErr || err == eventLoopQuitErr)
5101 CFSocketCreateRunLoopSource (NULL, socket, 0); 5180 {
5102 5181 EMACS_SET_SECS_USECS (select_timeout, 0, 0);
5103 #ifdef SELECT_INVALIDATE_CFSOCKET 5182 return select_and_poll_event (nfds, rfds, wfds, efds,
5104 CFSocketSetSocketFlags (socket, 0); 5183 &select_timeout);
5105 #endif 5184 }
5106 CFRunLoopAddSource (runloop, source, kCFRunLoopDefaultMode); 5185 else
5107 #ifdef SELECT_INVALIDATE_CFSOCKET 5186 {
5108 CFRelease (source); 5187 FD_ZERO (rfds);
5109 *s = socket; 5188 if (wfds)
5110 #else 5189 FD_ZERO (wfds);
5111 CFRelease (socket); 5190 return 0;
5112 *s = source; 5191 }
5113 #endif
5114 s++;
5115 }
5116
5117 err = ReceiveNextEvent (0, NULL, timeout_sec, kEventLeaveInQueue, NULL);
5118
5119 do
5120 {
5121 --s;
5122 #ifdef SELECT_INVALIDATE_CFSOCKET
5123 CFSocketInvalidate (*s);
5124 #else
5125 CFRunLoopRemoveSource (runloop, *s, kCFRunLoopDefaultMode);
5126 #endif
5127 CFRelease (*s);
5128 }
5129 while (s != shead);
5130
5131 xfree (shead);
5132
5133 if (err)
5134 {
5135 FD_ZERO (rfds);
5136 r = 0;
5137 }
5138 else
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
5147 UNBLOCK_INPUT;
5148
5149 return r;
5150 }
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; 5198
5158
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;
5166 EMACS_GET_TIME (now); 5202 EMACS_GET_TIME (now);
5167 EMACS_ADD_TIME (end_time, now, remaining_time); 5203 EMACS_ADD_TIME (end_time, now, remaining_time);
5170 do 5206 do
5171 { 5207 {
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 {
5187 EMACS_GET_TIME (now); 5223 EMACS_GET_TIME (now);
5188 EMACS_SUB_TIME (remaining_time, end_time, now); 5224 EMACS_SUB_TIME (remaining_time, end_time, now);
5189 } 5225 }
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
5202 /* Set up environment variables so that Emacs can correctly find its 5234 /* Set up environment variables so that Emacs can correctly find its
5203 support files when packaged as an application bundle. Directories 5235 support files when packaged as an application bundle. Directories
5385 5417
5386 defsubr (&Smac_coerce_ae_data); 5418 defsubr (&Smac_coerce_ae_data);
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);
5393 defsubr (&Smac_set_file_type); 5426 defsubr (&Smac_set_file_type);
5394 defsubr (&Smac_get_file_creator); 5427 defsubr (&Smac_get_file_creator);