mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-01 09:51:22 -08:00
[!TARGET_API_MAC_CARBON]: Don't include charset.h or coding.h.
(QCLIPBOARD): Remove variable. (syms_of_mac): Don't initialize it. (Fmac_paste_function, Fmac_cut_function, Fx_selection_exists_p): Remove functions. (syms_of_mac): Don't defsubr them. [TARGET_API_MAC_CARBON] (Qmime_charset, QNFD, QNFKD, QNFC, QNFKC) (QHFS_plus_D, QHFS_plus_C): New variables. (syms_of_mac) [TARGET_API_MAC_CARBON]: Initialize them. [TARGET_API_MAC_CARBON] (get_cfstring_encoding_from_lisp) (cfstring_create_normalized): New functions. [TARGET_API_MAC_CARBON] (Fmac_code_convert_string): Likewise. (syms_of_mac) [TARGET_API_MAC_CARBON]: Defsubr it.
This commit is contained in:
parent
f706a7b260
commit
eb32b29217
1 changed files with 232 additions and 176 deletions
408
src/mac.c
408
src/mac.c
|
|
@ -31,12 +31,13 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "sysselect.h"
|
||||
#include "systime.h"
|
||||
#include "blockinput.h"
|
||||
#include "charset.h"
|
||||
#include "coding.h"
|
||||
|
||||
#include "macterm.h"
|
||||
|
||||
#ifndef HAVE_CARBON
|
||||
#if TARGET_API_MAC_CARBON
|
||||
#include "charset.h"
|
||||
#include "coding.h"
|
||||
#else /* not TARGET_API_MAC_CARBON */
|
||||
#include <Files.h>
|
||||
#include <MacTypes.h>
|
||||
#include <TextUtils.h>
|
||||
|
|
@ -52,7 +53,7 @@ Boston, MA 02111-1307, USA. */
|
|||
#include <Processes.h>
|
||||
#include <EPPC.h>
|
||||
#include <MacLocales.h>
|
||||
#endif /* not HAVE_CARBON */
|
||||
#endif /* not TARGET_API_MAC_CARBON */
|
||||
|
||||
#include <utime.h>
|
||||
#include <dirent.h>
|
||||
|
|
@ -68,8 +69,6 @@ Boston, MA 02111-1307, USA. */
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
Lisp_Object QCLIPBOARD;
|
||||
|
||||
/* The system script code. */
|
||||
static int mac_system_script_code;
|
||||
|
||||
|
|
@ -331,7 +330,7 @@ cfdata_to_lisp (data)
|
|||
{
|
||||
CFIndex len = CFDataGetLength (data);
|
||||
Lisp_Object result = make_uninit_string (len);
|
||||
|
||||
|
||||
CFDataGetBytes (data, CFRangeMake (0, len), SDATA (result));
|
||||
|
||||
return result;
|
||||
|
|
@ -894,7 +893,7 @@ xrm_q_put_resource (database, quarks, value)
|
|||
if (i < 0)
|
||||
{
|
||||
max_nid++;
|
||||
XSETINT (node_id, max_nid);
|
||||
XSETINT (node_id, max_nid);
|
||||
hash_put (h, key, node_id, hash_code);
|
||||
}
|
||||
else
|
||||
|
|
@ -3515,169 +3514,9 @@ DEFUN ("posix-file-name-to-mac", Fposix_file_name_to_mac,
|
|||
}
|
||||
|
||||
|
||||
/* set interprogram-paste-function to mac-paste-function in mac-win.el
|
||||
to enable Emacs to obtain the contents of the Mac clipboard. */
|
||||
DEFUN ("mac-paste-function", Fmac_paste_function, Smac_paste_function, 0, 0, 0,
|
||||
doc: /* Return the contents of the Mac clipboard as a string. */)
|
||||
()
|
||||
{
|
||||
#if TARGET_API_MAC_CARBON
|
||||
OSStatus err;
|
||||
ScrapRef scrap;
|
||||
ScrapFlavorFlags sff;
|
||||
Size s;
|
||||
int i;
|
||||
char *data;
|
||||
|
||||
BLOCK_INPUT;
|
||||
err = GetCurrentScrap (&scrap);
|
||||
if (err == noErr)
|
||||
err = GetScrapFlavorFlags (scrap, kScrapFlavorTypeText, &sff);
|
||||
if (err == noErr)
|
||||
err = GetScrapFlavorSize (scrap, kScrapFlavorTypeText, &s);
|
||||
if (err == noErr && (data = (char*) alloca (s)))
|
||||
err = GetScrapFlavorData (scrap, kScrapFlavorTypeText, &s, data);
|
||||
UNBLOCK_INPUT;
|
||||
if (err != noErr || s == 0)
|
||||
return Qnil;
|
||||
|
||||
/* Emacs expects clipboard contents have Unix-style eol's */
|
||||
for (i = 0; i < s; i++)
|
||||
if (data[i] == '\r')
|
||||
data[i] = '\n';
|
||||
|
||||
return make_string (data, s);
|
||||
#else /* not TARGET_API_MAC_CARBON */
|
||||
Lisp_Object value;
|
||||
Handle my_handle;
|
||||
long scrap_offset, rc, i;
|
||||
|
||||
my_handle = NewHandle (0); /* allocate 0-length data area */
|
||||
|
||||
rc = GetScrap (my_handle, 'TEXT', &scrap_offset);
|
||||
if (rc < 0)
|
||||
return Qnil;
|
||||
|
||||
HLock (my_handle);
|
||||
|
||||
/* Emacs expects clipboard contents have Unix-style eol's */
|
||||
for (i = 0; i < rc; i++)
|
||||
if ((*my_handle)[i] == '\r')
|
||||
(*my_handle)[i] = '\n';
|
||||
|
||||
value = make_string (*my_handle, rc);
|
||||
|
||||
HUnlock (my_handle);
|
||||
|
||||
DisposeHandle (my_handle);
|
||||
|
||||
return value;
|
||||
#endif /* not TARGET_API_MAC_CARBON */
|
||||
}
|
||||
|
||||
|
||||
/* set interprogram-cut-function to mac-cut-function in mac-win.el
|
||||
to enable Emacs to write the top of the kill-ring to the Mac clipboard. */
|
||||
DEFUN ("mac-cut-function", Fmac_cut_function, Smac_cut_function, 1, 2, 0,
|
||||
doc: /* Put the value of the string parameter to the Mac clipboard. */)
|
||||
(value, push)
|
||||
Lisp_Object value, push;
|
||||
{
|
||||
char *buf;
|
||||
int len, i;
|
||||
|
||||
/* fixme: ignore the push flag for now */
|
||||
|
||||
CHECK_STRING (value);
|
||||
|
||||
len = SCHARS (value);
|
||||
buf = (char *) alloca (len+1);
|
||||
bcopy (SDATA (value), buf, len);
|
||||
buf[len] = '\0';
|
||||
|
||||
/* convert to Mac-style eol's before sending to clipboard */
|
||||
for (i = 0; i < len; i++)
|
||||
if (buf[i] == '\n')
|
||||
buf[i] = '\r';
|
||||
|
||||
#if TARGET_API_MAC_CARBON
|
||||
{
|
||||
ScrapRef scrap;
|
||||
|
||||
BLOCK_INPUT;
|
||||
ClearCurrentScrap ();
|
||||
if (GetCurrentScrap (&scrap) != noErr)
|
||||
{
|
||||
UNBLOCK_INPUT;
|
||||
error ("cannot get current scrap");
|
||||
}
|
||||
|
||||
if (PutScrapFlavor (scrap, kScrapFlavorTypeText, kScrapFlavorMaskNone, len,
|
||||
buf) != noErr)
|
||||
{
|
||||
UNBLOCK_INPUT;
|
||||
error ("cannot put to scrap");
|
||||
}
|
||||
UNBLOCK_INPUT;
|
||||
}
|
||||
#else /* not TARGET_API_MAC_CARBON */
|
||||
ZeroScrap ();
|
||||
PutScrap (len, 'TEXT', buf);
|
||||
#endif /* not TARGET_API_MAC_CARBON */
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
|
||||
DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
|
||||
0, 1, 0,
|
||||
doc: /* Whether there is an owner for the given X Selection.
|
||||
The arg should be the name of the selection in question, typically one of
|
||||
the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
|
||||
\(Those are literal upper-case symbol names, since that's what X expects.)
|
||||
For convenience, the symbol nil is the same as `PRIMARY',
|
||||
and t is the same as `SECONDARY'. */)
|
||||
(selection)
|
||||
Lisp_Object selection;
|
||||
{
|
||||
CHECK_SYMBOL (selection);
|
||||
|
||||
/* Return nil for PRIMARY and SECONDARY selections; for CLIPBOARD, check
|
||||
if the clipboard currently has valid text format contents. */
|
||||
|
||||
if (EQ (selection, QCLIPBOARD))
|
||||
{
|
||||
Lisp_Object val = Qnil;
|
||||
|
||||
#if TARGET_API_MAC_CARBON
|
||||
ScrapRef scrap;
|
||||
ScrapFlavorFlags sff;
|
||||
|
||||
BLOCK_INPUT;
|
||||
if (GetCurrentScrap (&scrap) == noErr)
|
||||
if (GetScrapFlavorFlags (scrap, kScrapFlavorTypeText, &sff) == noErr)
|
||||
val = Qt;
|
||||
UNBLOCK_INPUT;
|
||||
#else /* not TARGET_API_MAC_CARBON */
|
||||
Handle my_handle;
|
||||
long rc, scrap_offset;
|
||||
|
||||
my_handle = NewHandle (0);
|
||||
|
||||
rc = GetScrap (my_handle, 'TEXT', &scrap_offset);
|
||||
if (rc >= 0)
|
||||
val = Qt;
|
||||
|
||||
DisposeHandle (my_handle);
|
||||
#endif /* not TARGET_API_MAC_CARBON */
|
||||
|
||||
return val;
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
#if TARGET_API_MAC_CARBON
|
||||
static Lisp_Object Qxml;
|
||||
static Lisp_Object Qxml, Qmime_charset;
|
||||
static Lisp_Object QNFD, QNFKD, QNFC, QNFKC, QHFS_plus_D, QHFS_plus_C;
|
||||
|
||||
DEFUN ("mac-get-preference", Fmac_get_preference, Smac_get_preference, 1, 4, 0,
|
||||
doc: /* Return the application preference value for KEY.
|
||||
|
|
@ -3792,6 +3631,218 @@ otherwise. */)
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static CFStringEncoding
|
||||
get_cfstring_encoding_from_lisp (obj)
|
||||
Lisp_Object obj;
|
||||
{
|
||||
CFStringRef iana_name;
|
||||
CFStringEncoding encoding = kCFStringEncodingInvalidId;
|
||||
|
||||
if (INTEGERP (obj))
|
||||
return XINT (obj);
|
||||
|
||||
if (SYMBOLP (obj) && !NILP (obj) && !NILP (Fcoding_system_p (obj)))
|
||||
{
|
||||
Lisp_Object coding_spec, plist;
|
||||
|
||||
coding_spec = Fget (obj, Qcoding_system);
|
||||
plist = XVECTOR (coding_spec)->contents[3];
|
||||
obj = Fplist_get (XVECTOR (coding_spec)->contents[3], Qmime_charset);
|
||||
}
|
||||
|
||||
if (SYMBOLP (obj))
|
||||
obj = SYMBOL_NAME (obj);
|
||||
|
||||
if (STRINGP (obj))
|
||||
{
|
||||
iana_name = cfstring_create_with_string (obj);
|
||||
if (iana_name)
|
||||
{
|
||||
encoding = CFStringConvertIANACharSetNameToEncoding (iana_name);
|
||||
CFRelease (iana_name);
|
||||
}
|
||||
}
|
||||
|
||||
return encoding;
|
||||
}
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
|
||||
static CFStringRef
|
||||
cfstring_create_normalized (str, symbol)
|
||||
CFStringRef str;
|
||||
Lisp_Object symbol;
|
||||
{
|
||||
int form = -1;
|
||||
TextEncodingVariant variant;
|
||||
float initial_mag = 0.0;
|
||||
CFStringRef result = NULL;
|
||||
|
||||
if (EQ (symbol, QNFD))
|
||||
form = kCFStringNormalizationFormD;
|
||||
else if (EQ (symbol, QNFKD))
|
||||
form = kCFStringNormalizationFormKD;
|
||||
else if (EQ (symbol, QNFC))
|
||||
form = kCFStringNormalizationFormC;
|
||||
else if (EQ (symbol, QNFKC))
|
||||
form = kCFStringNormalizationFormKC;
|
||||
else if (EQ (symbol, QHFS_plus_D))
|
||||
{
|
||||
variant = kUnicodeHFSPlusDecompVariant;
|
||||
initial_mag = 1.5;
|
||||
}
|
||||
else if (EQ (symbol, QHFS_plus_C))
|
||||
{
|
||||
variant = kUnicodeHFSPlusCompVariant;
|
||||
initial_mag = 1.0;
|
||||
}
|
||||
|
||||
if (form >= 0)
|
||||
{
|
||||
CFMutableStringRef mut_str = CFStringCreateMutableCopy (NULL, 0, str);
|
||||
|
||||
if (mut_str)
|
||||
{
|
||||
CFStringNormalize (mut_str, form);
|
||||
result = mut_str;
|
||||
}
|
||||
}
|
||||
else if (initial_mag > 0.0)
|
||||
{
|
||||
UnicodeToTextInfo uni = NULL;
|
||||
UnicodeMapping map;
|
||||
CFIndex length;
|
||||
UniChar *in_text, *buffer = NULL, *out_buf = NULL;
|
||||
OSErr err = noErr;
|
||||
ByteCount out_read, out_size, out_len;
|
||||
|
||||
map.unicodeEncoding = CreateTextEncoding (kTextEncodingUnicodeDefault,
|
||||
kUnicodeNoSubset,
|
||||
kTextEncodingDefaultFormat);
|
||||
map.otherEncoding = CreateTextEncoding (kTextEncodingUnicodeDefault,
|
||||
variant,
|
||||
kTextEncodingDefaultFormat);
|
||||
map.mappingVersion = kUnicodeUseLatestMapping;
|
||||
|
||||
length = CFStringGetLength (str);
|
||||
out_size = (int)((float)length * initial_mag) * sizeof (UniChar);
|
||||
if (out_size < 32)
|
||||
out_size = 32;
|
||||
|
||||
in_text = (UniChar *)CFStringGetCharactersPtr (str);
|
||||
if (in_text == NULL)
|
||||
{
|
||||
buffer = xmalloc (sizeof (UniChar) * length);
|
||||
if (buffer)
|
||||
{
|
||||
CFStringGetCharacters (str, CFRangeMake (0, length), buffer);
|
||||
in_text = buffer;
|
||||
}
|
||||
}
|
||||
|
||||
if (in_text)
|
||||
err = CreateUnicodeToTextInfo(&map, &uni);
|
||||
while (err == noErr)
|
||||
{
|
||||
out_buf = xmalloc (out_size);
|
||||
if (out_buf == NULL)
|
||||
err = mFulErr;
|
||||
else
|
||||
err = ConvertFromUnicodeToText (uni, length * sizeof (UniChar),
|
||||
in_text,
|
||||
kUnicodeDefaultDirectionMask,
|
||||
0, NULL, NULL, NULL,
|
||||
out_size, &out_read, &out_len,
|
||||
out_buf);
|
||||
if (err == noErr && out_read < length * sizeof (UniChar))
|
||||
{
|
||||
xfree (out_buf);
|
||||
out_size += length;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (err == noErr)
|
||||
result = CFStringCreateWithCharacters (NULL, out_buf,
|
||||
out_len / sizeof (UniChar));
|
||||
if (uni)
|
||||
DisposeUnicodeToTextInfo (&uni);
|
||||
if (out_buf)
|
||||
xfree (out_buf);
|
||||
if (buffer)
|
||||
xfree (buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = str;
|
||||
CFRetain (result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
DEFUN ("mac-code-convert-string", Fmac_code_convert_string, Smac_code_convert_string, 3, 4, 0,
|
||||
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.
|
||||
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.
|
||||
On successful conversion, returns the result string, else returns
|
||||
nil. */)
|
||||
(string, source, target, normalization_form)
|
||||
Lisp_Object string, source, target, normalization_form;
|
||||
{
|
||||
Lisp_Object result = Qnil;
|
||||
CFStringEncoding src_encoding, tgt_encoding;
|
||||
CFStringRef str = NULL;
|
||||
CFDataRef data = NULL;
|
||||
|
||||
CHECK_STRING (string);
|
||||
if (!INTEGERP (source) && !STRINGP (source))
|
||||
CHECK_SYMBOL (source);
|
||||
if (!INTEGERP (target) && !STRINGP (target))
|
||||
CHECK_SYMBOL (target);
|
||||
CHECK_SYMBOL (normalization_form);
|
||||
|
||||
BLOCK_INPUT;
|
||||
|
||||
src_encoding = get_cfstring_encoding_from_lisp (source);
|
||||
tgt_encoding = get_cfstring_encoding_from_lisp (target);
|
||||
|
||||
string = string_make_unibyte (string);
|
||||
if (src_encoding != kCFStringEncodingInvalidId
|
||||
&& tgt_encoding != kCFStringEncodingInvalidId)
|
||||
str = CFStringCreateWithBytes (NULL, SDATA (string), SBYTES (string),
|
||||
src_encoding, true);
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
|
||||
if (str)
|
||||
{
|
||||
CFStringRef saved_str = str;
|
||||
|
||||
str = cfstring_create_normalized (saved_str, normalization_form);
|
||||
CFRelease (saved_str);
|
||||
}
|
||||
#endif
|
||||
if (str)
|
||||
{
|
||||
data = CFStringCreateExternalRepresentation (NULL, str,
|
||||
tgt_encoding, '\0');
|
||||
CFRelease (str);
|
||||
}
|
||||
if (data)
|
||||
{
|
||||
result = cfdata_to_lisp (data);
|
||||
CFRelease (data);
|
||||
}
|
||||
|
||||
UNBLOCK_INPUT;
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif /* TARGET_API_MAC_CARBON */
|
||||
|
||||
|
||||
|
|
@ -4232,9 +4283,6 @@ mac_get_system_locale ()
|
|||
void
|
||||
syms_of_mac ()
|
||||
{
|
||||
QCLIPBOARD = intern ("CLIPBOARD");
|
||||
staticpro (&QCLIPBOARD);
|
||||
|
||||
#if TARGET_API_MAC_CARBON
|
||||
Qstring = intern ("string"); staticpro (&Qstring);
|
||||
Qnumber = intern ("number"); staticpro (&Qnumber);
|
||||
|
|
@ -4246,13 +4294,21 @@ syms_of_mac ()
|
|||
|
||||
Qxml = intern ("xml");
|
||||
staticpro (&Qxml);
|
||||
|
||||
Qmime_charset = intern ("mime-charset");
|
||||
staticpro (&Qmime_charset);
|
||||
|
||||
QNFD = intern ("NFD"); staticpro (&QNFD);
|
||||
QNFKD = intern ("NFKD"); staticpro (&QNFKD);
|
||||
QNFC = intern ("NFC"); staticpro (&QNFC);
|
||||
QNFKC = intern ("NFKC"); staticpro (&QNFKC);
|
||||
QHFS_plus_D = intern ("HFS+D"); staticpro (&QHFS_plus_D);
|
||||
QHFS_plus_C = intern ("HFS+C"); staticpro (&QHFS_plus_C);
|
||||
#endif
|
||||
|
||||
defsubr (&Smac_paste_function);
|
||||
defsubr (&Smac_cut_function);
|
||||
defsubr (&Sx_selection_exists_p);
|
||||
#if TARGET_API_MAC_CARBON
|
||||
defsubr (&Smac_get_preference);
|
||||
defsubr (&Smac_code_convert_string);
|
||||
#endif
|
||||
defsubr (&Smac_clear_font_name_table);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue