aboutsummaryrefslogtreecommitdiffstats
path: root/src/mac.c
diff options
context:
space:
mode:
authorKaroly Lorentey2005-01-06 15:00:09 +0000
committerKaroly Lorentey2005-01-06 15:00:09 +0000
commit0feecea9fb7079a2c1fbfee32a992449a22cf478 (patch)
tree0826d68e3dc2ce370c7bd4dae7db3cffc3568321 /src/mac.c
parent17d51b68fb4e7da4f18eff72c589b7ffc4f9c22c (diff)
parent1a63439b34c3455a317feda5c271dfdb7af0296b (diff)
downloademacs-0feecea9fb7079a2c1fbfee32a992449a22cf478.tar.gz
emacs-0feecea9fb7079a2c1fbfee32a992449a22cf478.zip
Merged in changes from CVS trunk.
Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-747 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-748 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-749 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-750 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-751 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-752 Update from CVS * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-78 Merge from emacs--cvs-trunk--0 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-79 Update from CVS * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-80 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-278
Diffstat (limited to 'src/mac.c')
-rw-r--r--src/mac.c344
1 files changed, 247 insertions, 97 deletions
diff --git a/src/mac.c b/src/mac.c
index 53e56cfb541..99e0d44830b 100644
--- a/src/mac.c
+++ b/src/mac.c
@@ -845,6 +845,8 @@ check_alarm ()
845} 845}
846 846
847 847
848extern Boolean mac_wait_next_event (EventRecord *, UInt32, Boolean);
849
848int 850int
849select (n, rfds, wfds, efds, timeout) 851select (n, rfds, wfds, efds, timeout)
850 int n; 852 int n;
@@ -853,49 +855,24 @@ select (n, rfds, wfds, efds, timeout)
853 SELECT_TYPE *efds; 855 SELECT_TYPE *efds;
854 struct timeval *timeout; 856 struct timeval *timeout;
855{ 857{
856#ifdef TARGET_API_MAC_CARBON 858#if TARGET_API_MAC_CARBON
857 return 1; 859 return 1;
858#else /* not TARGET_API_MAC_CARBON */ 860#else /* not TARGET_API_MAC_CARBON */
859 EMACS_TIME end_time, now;
860 EventRecord e; 861 EventRecord e;
862 UInt32 sleep_time = EMACS_SECS (*timeout) * 60 +
863 ((EMACS_USECS (*timeout) * 60) / 1000000);
861 864
862 /* Can only handle wait for keyboard input. */ 865 /* Can only handle wait for keyboard input. */
863 if (n > 1 || wfds || efds) 866 if (n > 1 || wfds || efds)
864 return -1; 867 return -1;
865 868
866 EMACS_GET_TIME (end_time); 869 /* Also return true if an event other than a keyDown has occurred.
867 EMACS_ADD_TIME (end_time, end_time, *timeout); 870 This causes kbd_buffer_get_event in keyboard.c to call
868 871 read_avail_input which in turn calls XTread_socket to poll for
869 do 872 these events. Otherwise these never get processed except but a
870 { 873 very slow poll timer. */
871 /* Also return true if an event other than a keyDown has 874 if (FD_ISSET (0, rfds) && mac_wait_next_event (&e, sleep_time, false))
872 occurred. This causes kbd_buffer_get_event in keyboard.c to 875 return 1;
873 call read_avail_input which in turn calls XTread_socket to
874 poll for these events. Otherwise these never get processed
875 except but a very slow poll timer. */
876 if (FD_ISSET (0, rfds) && EventAvail (everyEvent, &e))
877 return 1;
878
879 /* Also check movement of the mouse. */
880 {
881 Point mouse_pos;
882 static Point old_mouse_pos = {-1, -1};
883
884 GetMouse (&mouse_pos);
885 if (!EqualPt (mouse_pos, old_mouse_pos))
886 {
887 old_mouse_pos = mouse_pos;
888 return 1;
889 }
890 }
891
892 WaitNextEvent (0, &e, 1UL, NULL); /* Accept no event; wait 1
893 tic. by T.I. */
894
895 EMACS_GET_TIME (now);
896 EMACS_SUB_TIME (now, end_time, now);
897 }
898 while (!EMACS_TIME_NEG_P (now));
899 876
900 return 0; 877 return 0;
901#endif /* not TARGET_API_MAC_CARBON */ 878#endif /* not TARGET_API_MAC_CARBON */
@@ -1996,7 +1973,7 @@ run_mac_command (argv, workdir, infn, outfn, errfn)
1996 const char *workdir; 1973 const char *workdir;
1997 const char *infn, *outfn, *errfn; 1974 const char *infn, *outfn, *errfn;
1998{ 1975{
1999#ifdef TARGET_API_MAC_CARBON 1976#if TARGET_API_MAC_CARBON
2000 return -1; 1977 return -1;
2001#else /* not TARGET_API_MAC_CARBON */ 1978#else /* not TARGET_API_MAC_CARBON */
2002 char macappname[MAXPATHLEN+1], macworkdir[MAXPATHLEN+1]; 1979 char macappname[MAXPATHLEN+1], macworkdir[MAXPATHLEN+1];
@@ -2081,7 +2058,7 @@ run_mac_command (argv, workdir, infn, outfn, errfn)
2081 strcat (t, newargv[0]); 2058 strcat (t, newargv[0]);
2082#endif /* 0 */ 2059#endif /* 0 */
2083 Lisp_Object path; 2060 Lisp_Object path;
2084 openp (Vexec_path, build_string (newargv[0]), EXEC_SUFFIXES, &path, 2061 openp (Vexec_path, build_string (newargv[0]), Vexec_suffixes, &path,
2085 make_number (X_OK)); 2062 make_number (X_OK));
2086 2063
2087 if (NILP (path)) 2064 if (NILP (path))
@@ -2793,17 +2770,98 @@ and t is the same as `SECONDARY'. */)
2793 return Qnil; 2770 return Qnil;
2794} 2771}
2795 2772
2773extern void mac_clear_font_name_table P_ ((void));
2774
2775DEFUN ("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
2796#ifdef MAC_OSX 2784#ifdef MAC_OSX
2797#undef select 2785#undef select
2798 2786
2799extern int inhibit_window_system; 2787extern int inhibit_window_system;
2800extern int noninteractive; 2788extern int noninteractive;
2801 2789
2802/* When Emacs is started from the Finder, SELECT always immediately 2790/* Unlike in X11, window events in Carbon do not come from sockets.
2803 returns as if input is present when file descriptor 0 is polled for 2791 So we cannot simply use `select' to monitor two kinds of inputs:
2804 input. Strangely, when Emacs is run as a GUI application from the 2792 window events and process outputs. We emulate such functionality
2805 command line, it blocks in the same situation. This `wrapper' of 2793 by regarding fd 0 as the window event channel and simultaneously
2806 the system call SELECT corrects this discrepancy. */ 2794 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
2818static void
2819socket_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
2834static int
2835select_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
2807int 2865int
2808sys_select (n, rfds, wfds, efds, timeout) 2866sys_select (n, rfds, wfds, efds, timeout)
2809 int n; 2867 int n;
@@ -2813,91 +2871,182 @@ sys_select (n, rfds, wfds, efds, timeout)
2813 struct timeval *timeout; 2871 struct timeval *timeout;
2814{ 2872{
2815 OSErr err; 2873 OSErr err;
2816 EMACS_TIME end_time, now, remaining_time; 2874 int i, r;
2817 2875 EMACS_TIME select_timeout;
2876
2818 if (inhibit_window_system || noninteractive 2877 if (inhibit_window_system || noninteractive
2819 || rfds == NULL || !FD_ISSET (0, rfds)) 2878 || rfds == NULL || !FD_ISSET (0, rfds))
2820 return select (n, rfds, wfds, efds, timeout); 2879 return select (n, rfds, wfds, efds, timeout);
2821 2880
2881 FD_CLR (0, rfds);
2882
2822 if (wfds == NULL && efds == NULL) 2883 if (wfds == NULL && efds == NULL)
2823 { 2884 {
2824 int i; 2885 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);
2825 2893
2826 for (i = 1; i < n; i++) 2894 for (i = 1; i < n; i++)
2827 if (FD_ISSET (i, rfds)) 2895 if (FD_ISSET (i, rfds))
2828 break; 2896 nsocks++;
2829 if (i == n)
2830 {
2831 EventTimeout timeout_sec =
2832 (timeout
2833 ? (EMACS_SECS (*timeout) * kEventDurationSecond
2834 + EMACS_USECS (*timeout) * kEventDurationMicrosecond)
2835 : kEventDurationForever);
2836 2897
2898 if (nsocks == 0)
2899 {
2837 BLOCK_INPUT; 2900 BLOCK_INPUT;
2838 err = ReceiveNextEvent (0, NULL, timeout_sec, 2901 err = ReceiveNextEvent (0, NULL, timeout_sec,
2839 kEventLeaveInQueue, NULL); 2902 kEventLeaveInQueue, NULL);
2840 UNBLOCK_INPUT; 2903 UNBLOCK_INPUT;
2841 if (err == noErr) 2904 if (err == noErr)
2842 { 2905 {
2843 FD_ZERO (rfds);
2844 FD_SET (0, rfds); 2906 FD_SET (0, rfds);
2845 return 1; 2907 return 1;
2846 } 2908 }
2847 else 2909 else
2848 return 0; 2910 return 0;
2849 } 2911 }
2850 }
2851 2912
2852 if (timeout) 2913 /* Avoid initial overhead of RunLoop setup for the case that
2853 { 2914 some input is already available. */
2854 remaining_time = *timeout; 2915 EMACS_SET_SECS_USECS (select_timeout, 0, 0);
2855 EMACS_GET_TIME (now); 2916 r = select_and_poll_event (n, rfds, wfds, efds, &select_timeout);
2856 EMACS_ADD_TIME (end_time, now, remaining_time); 2917 if (r != 0 || timeout_sec == 0.0)
2857 } 2918 return r;
2858 FD_CLR (0, rfds);
2859 do
2860 {
2861 EMACS_TIME select_timeout;
2862 SELECT_TYPE orfds = *rfds;
2863 int r;
2864 2919
2865 EMACS_SET_SECS_USECS (select_timeout, 0, 20000); 2920 *rfds = orfds;
2866 2921
2867 if (timeout && EMACS_TIME_LT (remaining_time, select_timeout)) 2922#ifdef SELECT_USE_CFSOCKET
2868 select_timeout = remaining_time; 2923 if (timeout_sec > 0 && timeout_sec <= SELECT_TIMEOUT_THRESHOLD_RUNLOOP)
2924 goto poll_periodically;
2869 2925
2870 r = select (n, &orfds, wfds, efds, &select_timeout); 2926 {
2871 BLOCK_INPUT; 2927 CFRunLoopRef runloop =
2872 err = ReceiveNextEvent (0, NULL, kEventDurationNoWait, 2928 (CFRunLoopRef) GetCFRunLoopFromEventLoop (GetCurrentEventLoop ());
2873 kEventLeaveInQueue, NULL); 2929 EventTypeSpec specs[] = {{EVENT_CLASS_SOCK, 0}};
2874 UNBLOCK_INPUT; 2930#ifdef SELECT_INVALIDATE_CFSOCKET
2875 if (r > 0) 2931 CFSocketRef *shead, *s;
2876 { 2932#else
2877 *rfds = orfds; 2933 CFRunLoopSourceRef *shead, *s;
2878 if (err == noErr) 2934#endif
2935
2936 BLOCK_INPUT;
2937
2938#ifdef SELECT_INVALIDATE_CFSOCKET
2939 shead = xmalloc (sizeof (CFSocketRef) * nsocks);
2940#else
2941 shead = xmalloc (sizeof (CFRunLoopSourceRef) * nsocks);
2942#endif
2943 s = shead;
2944 for (i = 1; i < n; i++)
2945 if (FD_ISSET (i, rfds))
2879 { 2946 {
2880 FD_SET (0, rfds); 2947 CFSocketRef socket =
2881 r++; 2948 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++;
2882 } 2965 }
2883 return r;
2884 }
2885 else if (err == noErr)
2886 {
2887 FD_ZERO (rfds);
2888 FD_SET (0, rfds);
2889 return 1;
2890 }
2891 2966
2892 if (timeout) 2967 err = ReceiveNextEvent (0, NULL, timeout_sec, kEventLeaveInQueue, NULL);
2893 { 2968
2894 EMACS_GET_TIME (now); 2969 do
2895 EMACS_SUB_TIME (remaining_time, end_time, now); 2970 {
2896 } 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 */
2897 } 3002 }
2898 while (!timeout || EMACS_TIME_LT (now, end_time));
2899 3003
2900 return 0; 3004 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 }
2901} 3050}
2902 3051
2903/* Set up environment variables so that Emacs can correctly find its 3052/* Set up environment variables so that Emacs can correctly find its
@@ -3043,6 +3192,7 @@ syms_of_mac ()
3043 defsubr (&Smac_paste_function); 3192 defsubr (&Smac_paste_function);
3044 defsubr (&Smac_cut_function); 3193 defsubr (&Smac_cut_function);
3045 defsubr (&Sx_selection_exists_p); 3194 defsubr (&Sx_selection_exists_p);
3195 defsubr (&Smac_clear_font_name_table);
3046 3196
3047 defsubr (&Sdo_applescript); 3197 defsubr (&Sdo_applescript);
3048 defsubr (&Smac_file_name_to_posix); 3198 defsubr (&Smac_file_name_to_posix);