845 |
} |
} |
846 |
|
|
847 |
|
|
848 |
|
extern Boolean mac_wait_next_event (EventRecord *, UInt32, Boolean); |
849 |
|
|
850 |
int |
int |
851 |
select (n, rfds, wfds, efds, timeout) |
select (n, rfds, wfds, efds, timeout) |
852 |
int n; |
int n; |
855 |
SELECT_TYPE *efds; |
SELECT_TYPE *efds; |
856 |
struct timeval *timeout; |
struct timeval *timeout; |
857 |
{ |
{ |
858 |
#ifdef TARGET_API_MAC_CARBON |
#if TARGET_API_MAC_CARBON |
859 |
return 1; |
return 1; |
860 |
#else /* not TARGET_API_MAC_CARBON */ |
#else /* not TARGET_API_MAC_CARBON */ |
|
EMACS_TIME end_time, now; |
|
861 |
EventRecord e; |
EventRecord e; |
862 |
|
UInt32 sleep_time = EMACS_SECS (*timeout) * 60 + |
863 |
|
((EMACS_USECS (*timeout) * 60) / 1000000); |
864 |
|
|
865 |
/* Can only handle wait for keyboard input. */ |
/* Can only handle wait for keyboard input. */ |
866 |
if (n > 1 || wfds || efds) |
if (n > 1 || wfds || efds) |
867 |
return -1; |
return -1; |
868 |
|
|
869 |
EMACS_GET_TIME (end_time); |
/* Also return true if an event other than a keyDown has occurred. |
870 |
EMACS_ADD_TIME (end_time, end_time, *timeout); |
This causes kbd_buffer_get_event in keyboard.c to call |
871 |
|
read_avail_input which in turn calls XTread_socket to poll for |
872 |
do |
these events. Otherwise these never get processed except but a |
873 |
{ |
very slow poll timer. */ |
874 |
/* Also return true if an event other than a keyDown has |
if (FD_ISSET (0, rfds) && mac_wait_next_event (&e, sleep_time, false)) |
875 |
occurred. This causes kbd_buffer_get_event in keyboard.c to |
return 1; |
|
call read_avail_input which in turn calls XTread_socket to |
|
|
poll for these events. Otherwise these never get processed |
|
|
except but a very slow poll timer. */ |
|
|
if (FD_ISSET (0, rfds) && EventAvail (everyEvent, &e)) |
|
|
return 1; |
|
|
|
|
|
/* Also check movement of the mouse. */ |
|
|
{ |
|
|
Point mouse_pos; |
|
|
static Point old_mouse_pos = {-1, -1}; |
|
|
|
|
|
GetMouse (&mouse_pos); |
|
|
if (!EqualPt (mouse_pos, old_mouse_pos)) |
|
|
{ |
|
|
old_mouse_pos = mouse_pos; |
|
|
return 1; |
|
|
} |
|
|
} |
|
|
|
|
|
WaitNextEvent (0, &e, 1UL, NULL); /* Accept no event; wait 1 |
|
|
tic. by T.I. */ |
|
|
|
|
|
EMACS_GET_TIME (now); |
|
|
EMACS_SUB_TIME (now, end_time, now); |
|
|
} |
|
|
while (!EMACS_TIME_NEG_P (now)); |
|
876 |
|
|
877 |
return 0; |
return 0; |
878 |
#endif /* not TARGET_API_MAC_CARBON */ |
#endif /* not TARGET_API_MAC_CARBON */ |
1973 |
const char *workdir; |
const char *workdir; |
1974 |
const char *infn, *outfn, *errfn; |
const char *infn, *outfn, *errfn; |
1975 |
{ |
{ |
1976 |
#ifdef TARGET_API_MAC_CARBON |
#if TARGET_API_MAC_CARBON |
1977 |
return -1; |
return -1; |
1978 |
#else /* not TARGET_API_MAC_CARBON */ |
#else /* not TARGET_API_MAC_CARBON */ |
1979 |
char macappname[MAXPATHLEN+1], macworkdir[MAXPATHLEN+1]; |
char macappname[MAXPATHLEN+1], macworkdir[MAXPATHLEN+1]; |
2058 |
strcat (t, newargv[0]); |
strcat (t, newargv[0]); |
2059 |
#endif /* 0 */ |
#endif /* 0 */ |
2060 |
Lisp_Object path; |
Lisp_Object path; |
2061 |
openp (Vexec_path, build_string (newargv[0]), EXEC_SUFFIXES, &path, |
openp (Vexec_path, build_string (newargv[0]), Vexec_suffixes, &path, |
2062 |
make_number (X_OK)); |
make_number (X_OK)); |
2063 |
|
|
2064 |
if (NILP (path)) |
if (NILP (path)) |
2770 |
return Qnil; |
return Qnil; |
2771 |
} |
} |
2772 |
|
|
2773 |
|
extern void mac_clear_font_name_table P_ ((void)); |
2774 |
|
|
2775 |
|
DEFUN ("mac-clear-font-name-table", Fmac_clear_font_name_table, Smac_clear_font_name_table, 0, 0, 0, |
2776 |
|
doc: /* Clear the font name table. */) |
2777 |
|
() |
2778 |
|
{ |
2779 |
|
check_mac (); |
2780 |
|
mac_clear_font_name_table (); |
2781 |
|
return Qnil; |
2782 |
|
} |
2783 |
|
|
2784 |
#ifdef MAC_OSX |
#ifdef MAC_OSX |
2785 |
#undef select |
#undef select |
2786 |
|
|
2787 |
extern int inhibit_window_system; |
extern int inhibit_window_system; |
2788 |
extern int noninteractive; |
extern int noninteractive; |
2789 |
|
|
2790 |
/* When Emacs is started from the Finder, SELECT always immediately |
/* Unlike in X11, window events in Carbon do not come from sockets. |
2791 |
returns as if input is present when file descriptor 0 is polled for |
So we cannot simply use `select' to monitor two kinds of inputs: |
2792 |
input. Strangely, when Emacs is run as a GUI application from the |
window events and process outputs. We emulate such functionality |
2793 |
command line, it blocks in the same situation. This `wrapper' of |
by regarding fd 0 as the window event channel and simultaneously |
2794 |
the system call SELECT corrects this discrepancy. */ |
monitoring both kinds of input channels. It is implemented by |
2795 |
|
dividing into some cases: |
2796 |
|
1. The window event channel is not involved. |
2797 |
|
-> Use `select'. |
2798 |
|
2. Sockets are not involved. |
2799 |
|
-> Use ReceiveNextEvent. |
2800 |
|
3. [If SELECT_USE_CFSOCKET is defined] |
2801 |
|
Only the window event channel and socket read channels are |
2802 |
|
involved, and timeout is not too short (greater than |
2803 |
|
SELECT_TIMEOUT_THRESHHOLD_RUNLOOP seconds). |
2804 |
|
-> Create CFSocket for each socket and add it into the current |
2805 |
|
event RunLoop so that an `ready-to-read' event can be posted |
2806 |
|
to the event queue that is also used for window events. Then |
2807 |
|
ReceiveNextEvent can wait for both kinds of inputs. |
2808 |
|
4. Otherwise. |
2809 |
|
-> Periodically poll the window input channel while repeatedly |
2810 |
|
executing `select' with a short timeout |
2811 |
|
(SELECT_POLLING_PERIOD_USEC microseconds). */ |
2812 |
|
|
2813 |
|
#define SELECT_POLLING_PERIOD_USEC 20000 |
2814 |
|
#ifdef SELECT_USE_CFSOCKET |
2815 |
|
#define SELECT_TIMEOUT_THRESHOLD_RUNLOOP 0.2 |
2816 |
|
#define EVENT_CLASS_SOCK 'Sock' |
2817 |
|
|
2818 |
|
static void |
2819 |
|
socket_callback (s, type, address, data, info) |
2820 |
|
CFSocketRef s; |
2821 |
|
CFSocketCallBackType type; |
2822 |
|
CFDataRef address; |
2823 |
|
const void *data; |
2824 |
|
void *info; |
2825 |
|
{ |
2826 |
|
EventRef event; |
2827 |
|
|
2828 |
|
CreateEvent (NULL, EVENT_CLASS_SOCK, 0, 0, kEventAttributeNone, &event); |
2829 |
|
PostEventToQueue (GetCurrentEventQueue (), event, kEventPriorityStandard); |
2830 |
|
ReleaseEvent (event); |
2831 |
|
} |
2832 |
|
#endif /* SELECT_USE_CFSOCKET */ |
2833 |
|
|
2834 |
|
static int |
2835 |
|
select_and_poll_event (n, rfds, wfds, efds, timeout) |
2836 |
|
int n; |
2837 |
|
SELECT_TYPE *rfds; |
2838 |
|
SELECT_TYPE *wfds; |
2839 |
|
SELECT_TYPE *efds; |
2840 |
|
struct timeval *timeout; |
2841 |
|
{ |
2842 |
|
int r; |
2843 |
|
OSErr err; |
2844 |
|
|
2845 |
|
r = select (n, rfds, wfds, efds, timeout); |
2846 |
|
if (r != -1) |
2847 |
|
{ |
2848 |
|
BLOCK_INPUT; |
2849 |
|
err = ReceiveNextEvent (0, NULL, kEventDurationNoWait, |
2850 |
|
kEventLeaveInQueue, NULL); |
2851 |
|
UNBLOCK_INPUT; |
2852 |
|
if (err == noErr) |
2853 |
|
{ |
2854 |
|
FD_SET (0, rfds); |
2855 |
|
r++; |
2856 |
|
} |
2857 |
|
} |
2858 |
|
return r; |
2859 |
|
} |
2860 |
|
|
2861 |
|
#ifndef MAC_OS_X_VERSION_10_2 |
2862 |
|
#undef SELECT_INVALIDATE_CFSOCKET |
2863 |
|
#endif |
2864 |
|
|
2865 |
int |
int |
2866 |
sys_select (n, rfds, wfds, efds, timeout) |
sys_select (n, rfds, wfds, efds, timeout) |
2867 |
int n; |
int n; |
2871 |
struct timeval *timeout; |
struct timeval *timeout; |
2872 |
{ |
{ |
2873 |
OSErr err; |
OSErr err; |
2874 |
EMACS_TIME end_time, now, remaining_time; |
int i, r; |
2875 |
|
EMACS_TIME select_timeout; |
2876 |
|
|
2877 |
if (inhibit_window_system || noninteractive |
if (inhibit_window_system || noninteractive |
2878 |
|| rfds == NULL || !FD_ISSET (0, rfds)) |
|| rfds == NULL || !FD_ISSET (0, rfds)) |
2879 |
return select (n, rfds, wfds, efds, timeout); |
return select (n, rfds, wfds, efds, timeout); |
2880 |
|
|
2881 |
|
FD_CLR (0, rfds); |
2882 |
|
|
2883 |
if (wfds == NULL && efds == NULL) |
if (wfds == NULL && efds == NULL) |
2884 |
{ |
{ |
2885 |
int i; |
int nsocks = 0; |
2886 |
|
SELECT_TYPE orfds = *rfds; |
2887 |
|
|
2888 |
|
EventTimeout timeout_sec = |
2889 |
|
(timeout |
2890 |
|
? (EMACS_SECS (*timeout) * kEventDurationSecond |
2891 |
|
+ EMACS_USECS (*timeout) * kEventDurationMicrosecond) |
2892 |
|
: kEventDurationForever); |
2893 |
|
|
2894 |
for (i = 1; i < n; i++) |
for (i = 1; i < n; i++) |
2895 |
if (FD_ISSET (i, rfds)) |
if (FD_ISSET (i, rfds)) |
2896 |
break; |
nsocks++; |
|
if (i == n) |
|
|
{ |
|
|
EventTimeout timeout_sec = |
|
|
(timeout |
|
|
? (EMACS_SECS (*timeout) * kEventDurationSecond |
|
|
+ EMACS_USECS (*timeout) * kEventDurationMicrosecond) |
|
|
: kEventDurationForever); |
|
2897 |
|
|
2898 |
|
if (nsocks == 0) |
2899 |
|
{ |
2900 |
BLOCK_INPUT; |
BLOCK_INPUT; |
2901 |
err = ReceiveNextEvent (0, NULL, timeout_sec, |
err = ReceiveNextEvent (0, NULL, timeout_sec, |
2902 |
kEventLeaveInQueue, NULL); |
kEventLeaveInQueue, NULL); |
2903 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
2904 |
if (err == noErr) |
if (err == noErr) |
2905 |
{ |
{ |
|
FD_ZERO (rfds); |
|
2906 |
FD_SET (0, rfds); |
FD_SET (0, rfds); |
2907 |
return 1; |
return 1; |
2908 |
} |
} |
2909 |
else |
else |
2910 |
return 0; |
return 0; |
2911 |
} |
} |
|
} |
|
2912 |
|
|
2913 |
if (timeout) |
/* Avoid initial overhead of RunLoop setup for the case that |
2914 |
{ |
some input is already available. */ |
2915 |
remaining_time = *timeout; |
EMACS_SET_SECS_USECS (select_timeout, 0, 0); |
2916 |
EMACS_GET_TIME (now); |
r = select_and_poll_event (n, rfds, wfds, efds, &select_timeout); |
2917 |
EMACS_ADD_TIME (end_time, now, remaining_time); |
if (r != 0 || timeout_sec == 0.0) |
2918 |
} |
return r; |
2919 |
FD_CLR (0, rfds); |
|
2920 |
do |
*rfds = orfds; |
2921 |
{ |
|
2922 |
EMACS_TIME select_timeout; |
#ifdef SELECT_USE_CFSOCKET |
2923 |
SELECT_TYPE orfds = *rfds; |
if (timeout_sec > 0 && timeout_sec <= SELECT_TIMEOUT_THRESHOLD_RUNLOOP) |
2924 |
int r; |
goto poll_periodically; |
2925 |
|
|
2926 |
EMACS_SET_SECS_USECS (select_timeout, 0, 20000); |
{ |
2927 |
|
CFRunLoopRef runloop = |
2928 |
|
(CFRunLoopRef) GetCFRunLoopFromEventLoop (GetCurrentEventLoop ()); |
2929 |
|
EventTypeSpec specs[] = {{EVENT_CLASS_SOCK, 0}}; |
2930 |
|
#ifdef SELECT_INVALIDATE_CFSOCKET |
2931 |
|
CFSocketRef *shead, *s; |
2932 |
|
#else |
2933 |
|
CFRunLoopSourceRef *shead, *s; |
2934 |
|
#endif |
2935 |
|
|
2936 |
if (timeout && EMACS_TIME_LT (remaining_time, select_timeout)) |
BLOCK_INPUT; |
|
select_timeout = remaining_time; |
|
2937 |
|
|
2938 |
r = select (n, &orfds, wfds, efds, &select_timeout); |
#ifdef SELECT_INVALIDATE_CFSOCKET |
2939 |
BLOCK_INPUT; |
shead = xmalloc (sizeof (CFSocketRef) * nsocks); |
2940 |
err = ReceiveNextEvent (0, NULL, kEventDurationNoWait, |
#else |
2941 |
kEventLeaveInQueue, NULL); |
shead = xmalloc (sizeof (CFRunLoopSourceRef) * nsocks); |
2942 |
UNBLOCK_INPUT; |
#endif |
2943 |
if (r > 0) |
s = shead; |
2944 |
{ |
for (i = 1; i < n; i++) |
2945 |
*rfds = orfds; |
if (FD_ISSET (i, rfds)) |
|
if (err == noErr) |
|
2946 |
{ |
{ |
2947 |
FD_SET (0, rfds); |
CFSocketRef socket = |
2948 |
r++; |
CFSocketCreateWithNative (NULL, i, kCFSocketReadCallBack, |
2949 |
|
socket_callback, NULL); |
2950 |
|
CFRunLoopSourceRef source = |
2951 |
|
CFSocketCreateRunLoopSource (NULL, socket, 0); |
2952 |
|
|
2953 |
|
#ifdef SELECT_INVALIDATE_CFSOCKET |
2954 |
|
CFSocketSetSocketFlags (socket, 0); |
2955 |
|
#endif |
2956 |
|
CFRunLoopAddSource (runloop, source, kCFRunLoopDefaultMode); |
2957 |
|
#ifdef SELECT_INVALIDATE_CFSOCKET |
2958 |
|
CFRelease (source); |
2959 |
|
*s = socket; |
2960 |
|
#else |
2961 |
|
CFRelease (socket); |
2962 |
|
*s = source; |
2963 |
|
#endif |
2964 |
|
s++; |
2965 |
} |
} |
|
return r; |
|
|
} |
|
|
else if (err == noErr) |
|
|
{ |
|
|
FD_ZERO (rfds); |
|
|
FD_SET (0, rfds); |
|
|
return 1; |
|
|
} |
|
2966 |
|
|
2967 |
if (timeout) |
err = ReceiveNextEvent (0, NULL, timeout_sec, kEventLeaveInQueue, NULL); |
2968 |
{ |
|
2969 |
EMACS_GET_TIME (now); |
do |
2970 |
EMACS_SUB_TIME (remaining_time, end_time, now); |
{ |
2971 |
} |
--s; |
2972 |
|
#ifdef SELECT_INVALIDATE_CFSOCKET |
2973 |
|
CFSocketInvalidate (*s); |
2974 |
|
#else |
2975 |
|
CFRunLoopRemoveSource (runloop, *s, kCFRunLoopDefaultMode); |
2976 |
|
#endif |
2977 |
|
CFRelease (*s); |
2978 |
|
} |
2979 |
|
while (s != shead); |
2980 |
|
|
2981 |
|
xfree (shead); |
2982 |
|
|
2983 |
|
if (err) |
2984 |
|
{ |
2985 |
|
FD_ZERO (rfds); |
2986 |
|
r = 0; |
2987 |
|
} |
2988 |
|
else |
2989 |
|
{ |
2990 |
|
FlushEventsMatchingListFromQueue (GetCurrentEventQueue (), |
2991 |
|
GetEventTypeCount (specs), |
2992 |
|
specs); |
2993 |
|
EMACS_SET_SECS_USECS (select_timeout, 0, 0); |
2994 |
|
r = select_and_poll_event (n, rfds, wfds, efds, &select_timeout); |
2995 |
|
} |
2996 |
|
|
2997 |
|
UNBLOCK_INPUT; |
2998 |
|
|
2999 |
|
return r; |
3000 |
|
} |
3001 |
|
#endif /* SELECT_USE_CFSOCKET */ |
3002 |
} |
} |
|
while (!timeout || EMACS_TIME_LT (now, end_time)); |
|
3003 |
|
|
3004 |
return 0; |
poll_periodically: |
3005 |
|
{ |
3006 |
|
EMACS_TIME end_time, now, remaining_time; |
3007 |
|
SELECT_TYPE orfds = *rfds, owfds, oefds; |
3008 |
|
|
3009 |
|
if (wfds) |
3010 |
|
owfds = *wfds; |
3011 |
|
if (efds) |
3012 |
|
oefds = *efds; |
3013 |
|
if (timeout) |
3014 |
|
{ |
3015 |
|
remaining_time = *timeout; |
3016 |
|
EMACS_GET_TIME (now); |
3017 |
|
EMACS_ADD_TIME (end_time, now, remaining_time); |
3018 |
|
} |
3019 |
|
|
3020 |
|
do |
3021 |
|
{ |
3022 |
|
EMACS_SET_SECS_USECS (select_timeout, 0, SELECT_POLLING_PERIOD_USEC); |
3023 |
|
if (timeout && EMACS_TIME_LT (remaining_time, select_timeout)) |
3024 |
|
select_timeout = remaining_time; |
3025 |
|
r = select_and_poll_event (n, rfds, wfds, efds, &select_timeout); |
3026 |
|
if (r != 0) |
3027 |
|
return r; |
3028 |
|
|
3029 |
|
*rfds = orfds; |
3030 |
|
if (wfds) |
3031 |
|
*wfds = owfds; |
3032 |
|
if (efds) |
3033 |
|
*efds = oefds; |
3034 |
|
|
3035 |
|
if (timeout) |
3036 |
|
{ |
3037 |
|
EMACS_GET_TIME (now); |
3038 |
|
EMACS_SUB_TIME (remaining_time, end_time, now); |
3039 |
|
} |
3040 |
|
} |
3041 |
|
while (!timeout || EMACS_TIME_LT (now, end_time)); |
3042 |
|
|
3043 |
|
FD_ZERO (rfds); |
3044 |
|
if (wfds) |
3045 |
|
FD_ZERO (wfds); |
3046 |
|
if (efds) |
3047 |
|
FD_ZERO (efds); |
3048 |
|
return 0; |
3049 |
|
} |
3050 |
} |
} |
3051 |
|
|
3052 |
/* Set up environment variables so that Emacs can correctly find its |
/* Set up environment variables so that Emacs can correctly find its |
3192 |
defsubr (&Smac_paste_function); |
defsubr (&Smac_paste_function); |
3193 |
defsubr (&Smac_cut_function); |
defsubr (&Smac_cut_function); |
3194 |
defsubr (&Sx_selection_exists_p); |
defsubr (&Sx_selection_exists_p); |
3195 |
|
defsubr (&Smac_clear_font_name_table); |
3196 |
|
|
3197 |
defsubr (&Sdo_applescript); |
defsubr (&Sdo_applescript); |
3198 |
defsubr (&Smac_file_name_to_posix); |
defsubr (&Smac_file_name_to_posix); |