Mercurial > emacs
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); |