/* Unix emulation routines for GNU Emacs on the Mac OS.
Copyright (C) 2000, 2001, 2002, 2003, 2004,
- 2005, 2006 Free Software Foundation, Inc.
+ 2005, 2006, 2007 Free Software Foundation, Inc.
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,
/* 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)
#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 *));
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));
}
GCPRO3 (database, quarks, value);
- BLOCK_INPUT;
-
app_id = kCFPreferencesCurrentApplication;
if (application)
{
if (app_id == NULL)
goto out;
}
+ if (!CFPreferencesAppSynchronize (app_id))
+ goto out;
key_set = CFSetCreateMutable (NULL, 0, &kCFCopyStringSetCallBacks);
if (key_set == NULL)
CFRelease (key_set);
CFRelease (app_id);
- UNBLOCK_INPUT;
-
UNGCPRO;
return database;
int res = open (mac_pathname, oflag);
/* if (oflag == O_WRONLY || oflag == O_RDWR) */
if (oflag & O_CREAT)
- fsetfileinfo (mac_pathname, 'EMAx', 'TEXT');
+ fsetfileinfo (mac_pathname, MAC_EMACS_CREATOR_CODE, 'TEXT');
return res;
#else /* not __MRC__ */
return open (mac_pathname, oflag);
{
#ifdef __MRC__
int result = creat (mac_pathname);
- fsetfileinfo (mac_pathname, 'EMAx', 'TEXT');
+ fsetfileinfo (mac_pathname, MAC_EMACS_CREATOR_CODE, 'TEXT');
return result;
#else /* not __MRC__ */
return creat (mac_pathname, mode);
{
#ifdef __MRC__
if (mode[0] == 'w' || mode[0] == 'a')
- fsetfileinfo (mac_pathname, 'EMAx', 'TEXT');
+ fsetfileinfo (mac_pathname, MAC_EMACS_CREATOR_CODE, 'TEXT');
#endif /* not __MRC__ */
return fopen (mac_pathname, mode);
}
OSType cCode;
CHECK_STRING (filename);
- cCode = mac_get_code_from_arg(code, 'EMAx');
+ cCode = mac_get_code_from_arg(code, MAC_EMACS_CREATOR_CODE);
if (NILP(Ffile_exists_p(filename)) || !NILP(Ffile_directory_p(filename))) {
return Qnil;
if (app_id == NULL)
goto out;
}
+ if (!CFPreferencesAppSynchronize (app_id))
+ goto out;
+
key_str = cfstring_create_with_string (XCAR (key));
if (key_str == NULL)
goto out;
doc: /* Convert STRING from SOURCE encoding to TARGET encoding.
The conversion is performed using the converter provided by the system.
Each encoding is specified by either a coding system symbol, a mime
-charset string, or an integer as a CFStringEncoding value. Nil for
-encoding means UTF-16 in native byte order, no byte order mark.
+charset string, or an integer as a CFStringEncoding value. An encoding
+of nil means UTF-16 in native byte order, no byte order mark.
On Mac OS X 10.2 and later, you can do Unicode Normalization by
specifying the optional argument NORMALIZATION-FORM with a symbol NFD,
NFKD, NFC, NFKC, HFS+D, or HFS+C.
3. [If SELECT_USE_CFSOCKET is set]
Only the window event channel and socket read/write channels are
involved, and timeout is not too short (greater than
- SELECT_TIMEOUT_THRESHHOLD_RUNLOOP seconds).
+ 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
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 */
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 ();
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 =
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)
CFSocketCreateWithNative (NULL, fd,
(kCFSocketReadCallBack
| kCFSocketConnectCallBack),
- socket_callback, &context);
+ socket_callback, NULL);
if (socket == NULL)
continue;
#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)))
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,
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)
{
/* 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 "<path to lisp dir>:<path to leim dir>:<path to
- site-lisp dir>". */
+ have the value "<path to site-lisp dir>:<path to lisp dir>:<path
+ to leim dir>". */
p = (char *) alloca (app_bundle_pathname_len + 50);
q = (char *) alloca (3 * app_bundle_pathname_len + 150);
if (!getenv ("EMACSLOADPATH"))
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')
}
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')
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