X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/d804ada24efd28b8574e2d9e5d87c364e4223e84..57fd5c55e459e10cd8a81a92ec2a6f8721f9c30f:/src/mac.c diff --git a/src/mac.c b/src/mac.c index d783243399..75a606b60b 100644 --- a/src/mac.c +++ b/src/mac.c @@ -6,7 +6,7 @@ This file is part of GNU Emacs. GNU Emacs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) +the Free Software Foundation; either version 3, or (at your option) any later version. GNU Emacs is distributed in the hope that it will be useful, @@ -79,6 +79,7 @@ static ComponentInstance as_scripting_component; /* The single script context used for all script executions. */ static OSAID as_script_context; +#ifndef MAC_OS_X #if TARGET_API_MAC_CARBON static int wakeup_from_rne_enabled_p = 0; #define ENABLE_WAKEUP_FROM_RNE (wakeup_from_rne_enabled_p = 1) @@ -87,6 +88,7 @@ static int wakeup_from_rne_enabled_p = 0; #define ENABLE_WAKEUP_FROM_RNE 0 #define DISABLE_WAKEUP_FROM_RNE 0 #endif +#endif #ifndef MAC_OSX static OSErr posix_pathname_to_fsspec P_ ((const char *, FSSpec *)); @@ -1127,18 +1129,15 @@ Lisp_Object cfdate_to_lisp (date) CFDateRef date; { - static const CFGregorianDate epoch_gdate = {1970, 1, 1, 0, 0, 0.0}; - static CFAbsoluteTime epoch = 0.0, sec; - int high, low; - - if (epoch == 0.0) - epoch = CFGregorianDateGetAbsoluteTime (epoch_gdate, NULL); + CFTimeInterval sec; + int high, low, microsec; - sec = CFDateGetAbsoluteTime (date) - epoch; + sec = CFDateGetAbsoluteTime (date) + kCFAbsoluteTimeIntervalSince1970; high = sec / 65536.0; low = sec - high * 65536.0; + microsec = (sec - floor (sec)) * 1000000.0; - return list3 (make_number (high), make_number (low), make_number (0)); + return list3 (make_number (high), make_number (low), make_number (microsec)); } @@ -4990,8 +4989,8 @@ extern int noninteractive; SELECT_TIMEOUT_THRESHOLD_RUNLOOP seconds). -> Create CFSocket for each socket and add it into the current event RunLoop so that the current event loop gets quit when - the socket becomes ready. Then ReceiveNextEvent can wait for - both kinds of inputs. + the socket becomes ready. Then CFRunLoopRunInMode can wait + for both kinds of inputs. 4. Otherwise. -> Periodically poll the window input channel while repeatedly executing `select' with a short timeout @@ -5013,12 +5012,6 @@ socket_callback (s, type, address, data, info) const void *data; void *info; { - int fd = CFSocketGetNative (s); - SELECT_TYPE *ofds = (SELECT_TYPE *)info; - - if ((type == kCFSocketReadCallBack && FD_ISSET (fd, &ofds[0])) - || (type == kCFSocketConnectCallBack && FD_ISSET (fd, &ofds[1]))) - QuitEventLoop (GetCurrentEventLoop ()); } #endif /* SELECT_USE_CFSOCKET */ @@ -5028,42 +5021,64 @@ select_and_poll_event (nfds, rfds, wfds, efds, timeout) SELECT_TYPE *rfds, *wfds, *efds; EMACS_TIME *timeout; { - OSStatus err = noErr; + int timedout_p = 0; int r = 0; + EMACS_TIME select_timeout; + EventTimeout timeoutval = + (timeout + ? (EMACS_SECS (*timeout) * kEventDurationSecond + + EMACS_USECS (*timeout) * kEventDurationMicrosecond) + : kEventDurationForever); + SELECT_TYPE orfds, owfds, oefds; - /* Try detect_input_pending before ReceiveNextEvent in the same + if (timeout == NULL) + { + if (rfds) orfds = *rfds; + if (wfds) owfds = *wfds; + if (efds) oefds = *efds; + } + + /* Try detect_input_pending before CFRunLoopRunInMode in the same BLOCK_INPUT block, in case that some input has already been read asynchronously. */ BLOCK_INPUT; - ENABLE_WAKEUP_FROM_RNE; - if (!detect_input_pending ()) + while (1) { - EMACS_TIME select_timeout; - EventTimeout timeoutval = - (timeout - ? (EMACS_SECS (*timeout) * kEventDurationSecond - + EMACS_USECS (*timeout) * kEventDurationMicrosecond) - : kEventDurationForever); + if (detect_input_pending ()) + break; EMACS_SET_SECS_USECS (select_timeout, 0, 0); r = select (nfds, rfds, wfds, efds, &select_timeout); + if (r != 0) + break; + if (timeoutval == 0.0) - err = eventLoopTimedOutErr; - else if (r == 0) + timedout_p = 1; + else { #if USE_CG_DRAWING mac_prepare_for_quickdraw (NULL); #endif - err = ReceiveNextEvent (0, NULL, timeoutval, - kEventLeaveInQueue, NULL); + if (CFRunLoopRunInMode (kCFRunLoopDefaultMode, + timeoutval >= 0 ? timeoutval : 100000, true) + == kCFRunLoopRunTimedOut) + timedout_p = 1; } + + if (timeout == NULL && timedout_p) + { + if (rfds) *rfds = orfds; + if (wfds) *wfds = owfds; + if (efds) *efds = oefds; + } + else + break; } - DISABLE_WAKEUP_FROM_RNE; UNBLOCK_INPUT; if (r != 0) return r; - else if (err == noErr) + else if (!timedout_p) { /* Pretend that `select' is interrupted by a signal. */ detect_input_pending (); @@ -5080,25 +5095,25 @@ sys_select (nfds, rfds, wfds, efds, timeout) SELECT_TYPE *rfds, *wfds, *efds; EMACS_TIME *timeout; { - OSStatus err = noErr; + int timedout_p = 0; int r; EMACS_TIME select_timeout; - static SELECT_TYPE ofds[3]; + SELECT_TYPE orfds, owfds, oefds; if (inhibit_window_system || noninteractive || nfds < 1 || rfds == NULL || !FD_ISSET (0, rfds)) return select (nfds, rfds, wfds, efds, timeout); FD_CLR (0, rfds); - ofds[0] = *rfds; + orfds = *rfds; if (wfds) - ofds[1] = *wfds; + owfds = *wfds; else - FD_ZERO (&ofds[1]); + FD_ZERO (&owfds); if (efds) - ofds[2] = *efds; + oefds = *efds; else { EventTimeout timeoutval = @@ -5126,25 +5141,23 @@ sys_select (nfds, rfds, wfds, efds, timeout) if (r != 0 || timeoutval == 0.0) return r; - *rfds = ofds[0]; + *rfds = orfds; if (wfds) - *wfds = ofds[1]; + *wfds = owfds; #if SELECT_USE_CFSOCKET if (timeoutval > 0 && timeoutval <= SELECT_TIMEOUT_THRESHOLD_RUNLOOP) goto poll_periodically; - /* Try detect_input_pending before ReceiveNextEvent in the same - BLOCK_INPUT block, in case that some input has already been - read asynchronously. */ + /* Try detect_input_pending before CFRunLoopRunInMode in the + same BLOCK_INPUT block, in case that some input has already + been read asynchronously. */ BLOCK_INPUT; - ENABLE_WAKEUP_FROM_RNE; if (!detect_input_pending ()) { int minfd, fd; CFRunLoopRef runloop = (CFRunLoopRef) GetCFRunLoopFromEventLoop (GetCurrentEventLoop ()); - static const CFSocketContext context = {0, ofds, NULL, NULL, NULL}; static CFMutableDictionaryRef sources; if (sources == NULL) @@ -5169,7 +5182,7 @@ sys_select (nfds, rfds, wfds, efds, timeout) CFSocketCreateWithNative (NULL, fd, (kCFSocketReadCallBack | kCFSocketConnectCallBack), - socket_callback, &context); + socket_callback, NULL); if (socket == NULL) continue; @@ -5186,8 +5199,10 @@ sys_select (nfds, rfds, wfds, efds, timeout) #if USE_CG_DRAWING mac_prepare_for_quickdraw (NULL); #endif - err = ReceiveNextEvent (0, NULL, timeoutval, - kEventLeaveInQueue, NULL); + if (CFRunLoopRunInMode (kCFRunLoopDefaultMode, + timeoutval >= 0 ? timeoutval : 100000, true) + == kCFRunLoopRunTimedOut) + timedout_p = 1; for (fd = minfd; fd < nfds; fd++) if (FD_ISSET (fd, rfds) || (wfds && FD_ISSET (fd, wfds))) @@ -5199,10 +5214,9 @@ sys_select (nfds, rfds, wfds, efds, timeout) CFRunLoopRemoveSource (runloop, source, kCFRunLoopDefaultMode); } } - DISABLE_WAKEUP_FROM_RNE; UNBLOCK_INPUT; - if (err == noErr || err == eventLoopQuitErr) + if (!timedout_p) { EMACS_SET_SECS_USECS (select_timeout, 0, 0); return select_and_poll_event (nfds, rfds, wfds, efds, @@ -5238,11 +5252,11 @@ sys_select (nfds, rfds, wfds, efds, timeout) if (r != 0) return r; - *rfds = ofds[0]; + *rfds = orfds; if (wfds) - *wfds = ofds[1]; + *wfds = owfds; if (efds) - *efds = ofds[2]; + *efds = oefds; if (timeout) { @@ -5318,8 +5332,8 @@ init_mac_osx_environment () /* P should have sufficient room for the pathname of the bundle plus the subpath in it leading to the respective directories. Q should have three times that much room because EMACSLOADPATH can - have the value "::". */ + have the value "::". */ p = (char *) alloca (app_bundle_pathname_len + 50); q = (char *) alloca (3 * app_bundle_pathname_len + 150); if (!getenv ("EMACSLOADPATH")) @@ -5327,12 +5341,12 @@ init_mac_osx_environment () q[0] = '\0'; strcpy (p, app_bundle_pathname); - strcat (p, "/Contents/Resources/lisp"); + strcat (p, "/Contents/Resources/site-lisp"); if (stat (p, &st) == 0 && (st.st_mode & S_IFMT) == S_IFDIR) strcat (q, p); strcpy (p, app_bundle_pathname); - strcat (p, "/Contents/Resources/leim"); + strcat (p, "/Contents/Resources/lisp"); if (stat (p, &st) == 0 && (st.st_mode & S_IFMT) == S_IFDIR) { if (q[0] != '\0') @@ -5341,7 +5355,7 @@ init_mac_osx_environment () } strcpy (p, app_bundle_pathname); - strcat (p, "/Contents/Resources/site-lisp"); + strcat (p, "/Contents/Resources/leim"); if (stat (p, &st) == 0 && (st.st_mode & S_IFMT) == S_IFDIR) { if (q[0] != '\0') @@ -5405,10 +5419,12 @@ init_mac_osx_environment () void mac_wakeup_from_rne () { +#ifndef MAC_OSX if (wakeup_from_rne_enabled_p) /* Post a harmless event so as to wake up from ReceiveNextEvent. */ mac_post_mouse_moved_event (); +#endif } #endif