aboutsummaryrefslogtreecommitdiffstats
path: root/src/mac.c
diff options
context:
space:
mode:
authorYAMAMOTO Mitsuharu2005-04-24 06:05:39 +0000
committerYAMAMOTO Mitsuharu2005-04-24 06:05:39 +0000
commiteb32b2921764763812938e96aef033e52edd38dc (patch)
tree6195f55113299c0bc289bb99c68b5fc52e029bc6 /src/mac.c
parentf706a7b26099f02c4784118aadebdbb135fc5008 (diff)
downloademacs-eb32b2921764763812938e96aef033e52edd38dc.tar.gz
emacs-eb32b2921764763812938e96aef033e52edd38dc.zip
[!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.
Diffstat (limited to 'src/mac.c')
-rw-r--r--src/mac.c408
1 files changed, 232 insertions, 176 deletions
diff --git a/src/mac.c b/src/mac.c
index 68e3bdfa065..0a1b94eb2c5 100644
--- a/src/mac.c
+++ b/src/mac.c
@@ -31,12 +31,13 @@ Boston, MA 02111-1307, USA. */
31#include "sysselect.h" 31#include "sysselect.h"
32#include "systime.h" 32#include "systime.h"
33#include "blockinput.h" 33#include "blockinput.h"
34#include "charset.h"
35#include "coding.h"
36 34
37#include "macterm.h" 35#include "macterm.h"
38 36
39#ifndef HAVE_CARBON 37#if TARGET_API_MAC_CARBON
38#include "charset.h"
39#include "coding.h"
40#else /* not TARGET_API_MAC_CARBON */
40#include <Files.h> 41#include <Files.h>
41#include <MacTypes.h> 42#include <MacTypes.h>
42#include <TextUtils.h> 43#include <TextUtils.h>
@@ -52,7 +53,7 @@ Boston, MA 02111-1307, USA. */
52#include <Processes.h> 53#include <Processes.h>
53#include <EPPC.h> 54#include <EPPC.h>
54#include <MacLocales.h> 55#include <MacLocales.h>
55#endif /* not HAVE_CARBON */ 56#endif /* not TARGET_API_MAC_CARBON */
56 57
57#include <utime.h> 58#include <utime.h>
58#include <dirent.h> 59#include <dirent.h>
@@ -68,8 +69,6 @@ Boston, MA 02111-1307, USA. */
68#include <unistd.h> 69#include <unistd.h>
69#endif 70#endif
70 71
71Lisp_Object QCLIPBOARD;
72
73/* The system script code. */ 72/* The system script code. */
74static int mac_system_script_code; 73static int mac_system_script_code;
75 74
@@ -331,7 +330,7 @@ cfdata_to_lisp (data)
331{ 330{
332 CFIndex len = CFDataGetLength (data); 331 CFIndex len = CFDataGetLength (data);
333 Lisp_Object result = make_uninit_string (len); 332 Lisp_Object result = make_uninit_string (len);
334 333
335 CFDataGetBytes (data, CFRangeMake (0, len), SDATA (result)); 334 CFDataGetBytes (data, CFRangeMake (0, len), SDATA (result));
336 335
337 return result; 336 return result;
@@ -894,7 +893,7 @@ xrm_q_put_resource (database, quarks, value)
894 if (i < 0) 893 if (i < 0)
895 { 894 {
896 max_nid++; 895 max_nid++;
897 XSETINT (node_id, max_nid); 896 XSETINT (node_id, max_nid);
898 hash_put (h, key, node_id, hash_code); 897 hash_put (h, key, node_id, hash_code);
899 } 898 }
900 else 899 else
@@ -3515,169 +3514,9 @@ DEFUN ("posix-file-name-to-mac", Fposix_file_name_to_mac,
3515} 3514}
3516 3515
3517 3516
3518/* set interprogram-paste-function to mac-paste-function in mac-win.el
3519 to enable Emacs to obtain the contents of the Mac clipboard. */
3520DEFUN ("mac-paste-function", Fmac_paste_function, Smac_paste_function, 0, 0, 0,
3521 doc: /* Return the contents of the Mac clipboard as a string. */)
3522 ()
3523{
3524#if TARGET_API_MAC_CARBON
3525 OSStatus err;
3526 ScrapRef scrap;
3527 ScrapFlavorFlags sff;
3528 Size s;
3529 int i;
3530 char *data;
3531
3532 BLOCK_INPUT;
3533 err = GetCurrentScrap (&scrap);
3534 if (err == noErr)
3535 err = GetScrapFlavorFlags (scrap, kScrapFlavorTypeText, &sff);
3536 if (err == noErr)
3537 err = GetScrapFlavorSize (scrap, kScrapFlavorTypeText, &s);
3538 if (err == noErr && (data = (char*) alloca (s)))
3539 err = GetScrapFlavorData (scrap, kScrapFlavorTypeText, &s, data);
3540 UNBLOCK_INPUT;
3541 if (err != noErr || s == 0)
3542 return Qnil;
3543
3544 /* Emacs expects clipboard contents have Unix-style eol's */
3545 for (i = 0; i < s; i++)
3546 if (data[i] == '\r')
3547 data[i] = '\n';
3548
3549 return make_string (data, s);
3550#else /* not TARGET_API_MAC_CARBON */
3551 Lisp_Object value;
3552 Handle my_handle;
3553 long scrap_offset, rc, i;
3554
3555 my_handle = NewHandle (0); /* allocate 0-length data area */
3556
3557 rc = GetScrap (my_handle, 'TEXT', &scrap_offset);
3558 if (rc < 0)
3559 return Qnil;
3560
3561 HLock (my_handle);
3562
3563 /* Emacs expects clipboard contents have Unix-style eol's */
3564 for (i = 0; i < rc; i++)
3565 if ((*my_handle)[i] == '\r')
3566 (*my_handle)[i] = '\n';
3567
3568 value = make_string (*my_handle, rc);
3569
3570 HUnlock (my_handle);
3571
3572 DisposeHandle (my_handle);
3573
3574 return value;
3575#endif /* not TARGET_API_MAC_CARBON */
3576}
3577
3578
3579/* set interprogram-cut-function to mac-cut-function in mac-win.el
3580 to enable Emacs to write the top of the kill-ring to the Mac clipboard. */
3581DEFUN ("mac-cut-function", Fmac_cut_function, Smac_cut_function, 1, 2, 0,
3582 doc: /* Put the value of the string parameter to the Mac clipboard. */)
3583 (value, push)
3584 Lisp_Object value, push;
3585{
3586 char *buf;
3587 int len, i;
3588
3589 /* fixme: ignore the push flag for now */
3590
3591 CHECK_STRING (value);
3592
3593 len = SCHARS (value);
3594 buf = (char *) alloca (len+1);
3595 bcopy (SDATA (value), buf, len);
3596 buf[len] = '\0';
3597
3598 /* convert to Mac-style eol's before sending to clipboard */
3599 for (i = 0; i < len; i++)
3600 if (buf[i] == '\n')
3601 buf[i] = '\r';
3602
3603#if TARGET_API_MAC_CARBON
3604 {
3605 ScrapRef scrap;
3606
3607 BLOCK_INPUT;
3608 ClearCurrentScrap ();
3609 if (GetCurrentScrap (&scrap) != noErr)
3610 {
3611 UNBLOCK_INPUT;
3612 error ("cannot get current scrap");
3613 }
3614
3615 if (PutScrapFlavor (scrap, kScrapFlavorTypeText, kScrapFlavorMaskNone, len,
3616 buf) != noErr)
3617 {
3618 UNBLOCK_INPUT;
3619 error ("cannot put to scrap");
3620 }
3621 UNBLOCK_INPUT;
3622 }
3623#else /* not TARGET_API_MAC_CARBON */
3624 ZeroScrap ();
3625 PutScrap (len, 'TEXT', buf);
3626#endif /* not TARGET_API_MAC_CARBON */
3627
3628 return Qnil;
3629}
3630
3631
3632DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
3633 0, 1, 0,
3634 doc: /* Whether there is an owner for the given X Selection.
3635The arg should be the name of the selection in question, typically one of
3636the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
3637\(Those are literal upper-case symbol names, since that's what X expects.)
3638For convenience, the symbol nil is the same as `PRIMARY',
3639and t is the same as `SECONDARY'. */)
3640 (selection)
3641 Lisp_Object selection;
3642{
3643 CHECK_SYMBOL (selection);
3644
3645 /* Return nil for PRIMARY and SECONDARY selections; for CLIPBOARD, check
3646 if the clipboard currently has valid text format contents. */
3647
3648 if (EQ (selection, QCLIPBOARD))
3649 {
3650 Lisp_Object val = Qnil;
3651
3652#if TARGET_API_MAC_CARBON
3653 ScrapRef scrap;
3654 ScrapFlavorFlags sff;
3655
3656 BLOCK_INPUT;
3657 if (GetCurrentScrap (&scrap) == noErr)
3658 if (GetScrapFlavorFlags (scrap, kScrapFlavorTypeText, &sff) == noErr)
3659 val = Qt;
3660 UNBLOCK_INPUT;
3661#else /* not TARGET_API_MAC_CARBON */
3662 Handle my_handle;
3663 long rc, scrap_offset;
3664
3665 my_handle = NewHandle (0);
3666
3667 rc = GetScrap (my_handle, 'TEXT', &scrap_offset);
3668 if (rc >= 0)
3669 val = Qt;
3670
3671 DisposeHandle (my_handle);
3672#endif /* not TARGET_API_MAC_CARBON */
3673
3674 return val;
3675 }
3676 return Qnil;
3677}
3678
3679#if TARGET_API_MAC_CARBON 3517#if TARGET_API_MAC_CARBON
3680static Lisp_Object Qxml; 3518static Lisp_Object Qxml, Qmime_charset;
3519static Lisp_Object QNFD, QNFKD, QNFC, QNFKC, QHFS_plus_D, QHFS_plus_C;
3681 3520
3682DEFUN ("mac-get-preference", Fmac_get_preference, Smac_get_preference, 1, 4, 0, 3521DEFUN ("mac-get-preference", Fmac_get_preference, Smac_get_preference, 1, 4, 0,
3683 doc: /* Return the application preference value for KEY. 3522 doc: /* Return the application preference value for KEY.
@@ -3792,6 +3631,218 @@ otherwise. */)
3792 3631
3793 return result; 3632 return result;
3794} 3633}
3634
3635
3636static CFStringEncoding
3637get_cfstring_encoding_from_lisp (obj)
3638 Lisp_Object obj;
3639{
3640 CFStringRef iana_name;
3641 CFStringEncoding encoding = kCFStringEncodingInvalidId;
3642
3643 if (INTEGERP (obj))
3644 return XINT (obj);
3645
3646 if (SYMBOLP (obj) && !NILP (obj) && !NILP (Fcoding_system_p (obj)))
3647 {
3648 Lisp_Object coding_spec, plist;
3649
3650 coding_spec = Fget (obj, Qcoding_system);
3651 plist = XVECTOR (coding_spec)->contents[3];
3652 obj = Fplist_get (XVECTOR (coding_spec)->contents[3], Qmime_charset);
3653 }
3654
3655 if (SYMBOLP (obj))
3656 obj = SYMBOL_NAME (obj);
3657
3658 if (STRINGP (obj))
3659 {
3660 iana_name = cfstring_create_with_string (obj);
3661 if (iana_name)
3662 {
3663 encoding = CFStringConvertIANACharSetNameToEncoding (iana_name);
3664 CFRelease (iana_name);
3665 }
3666 }
3667
3668 return encoding;
3669}
3670
3671#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
3672static CFStringRef
3673cfstring_create_normalized (str, symbol)
3674 CFStringRef str;
3675 Lisp_Object symbol;
3676{
3677 int form = -1;
3678 TextEncodingVariant variant;
3679 float initial_mag = 0.0;
3680 CFStringRef result = NULL;
3681
3682 if (EQ (symbol, QNFD))
3683 form = kCFStringNormalizationFormD;
3684 else if (EQ (symbol, QNFKD))
3685 form = kCFStringNormalizationFormKD;
3686 else if (EQ (symbol, QNFC))
3687 form = kCFStringNormalizationFormC;
3688 else if (EQ (symbol, QNFKC))
3689 form = kCFStringNormalizationFormKC;
3690 else if (EQ (symbol, QHFS_plus_D))
3691 {
3692 variant = kUnicodeHFSPlusDecompVariant;
3693 initial_mag = 1.5;
3694 }
3695 else if (EQ (symbol, QHFS_plus_C))
3696 {
3697 variant = kUnicodeHFSPlusCompVariant;
3698 initial_mag = 1.0;
3699 }
3700
3701 if (form >= 0)
3702 {
3703 CFMutableStringRef mut_str = CFStringCreateMutableCopy (NULL, 0, str);
3704
3705 if (mut_str)
3706 {
3707 CFStringNormalize (mut_str, form);
3708 result = mut_str;
3709 }
3710 }
3711 else if (initial_mag > 0.0)
3712 {
3713 UnicodeToTextInfo uni = NULL;
3714 UnicodeMapping map;
3715 CFIndex length;
3716 UniChar *in_text, *buffer = NULL, *out_buf = NULL;
3717 OSErr err = noErr;
3718 ByteCount out_read, out_size, out_len;
3719
3720 map.unicodeEncoding = CreateTextEncoding (kTextEncodingUnicodeDefault,
3721 kUnicodeNoSubset,
3722 kTextEncodingDefaultFormat);
3723 map.otherEncoding = CreateTextEncoding (kTextEncodingUnicodeDefault,
3724 variant,
3725 kTextEncodingDefaultFormat);
3726 map.mappingVersion = kUnicodeUseLatestMapping;
3727
3728 length = CFStringGetLength (str);
3729 out_size = (int)((float)length * initial_mag) * sizeof (UniChar);
3730 if (out_size < 32)
3731 out_size = 32;
3732
3733 in_text = (UniChar *)CFStringGetCharactersPtr (str);
3734 if (in_text == NULL)
3735 {
3736 buffer = xmalloc (sizeof (UniChar) * length);
3737 if (buffer)
3738 {
3739 CFStringGetCharacters (str, CFRangeMake (0, length), buffer);
3740 in_text = buffer;
3741 }
3742 }
3743
3744 if (in_text)
3745 err = CreateUnicodeToTextInfo(&map, &uni);
3746 while (err == noErr)
3747 {
3748 out_buf = xmalloc (out_size);
3749 if (out_buf == NULL)
3750 err = mFulErr;
3751 else
3752 err = ConvertFromUnicodeToText (uni, length * sizeof (UniChar),
3753 in_text,
3754 kUnicodeDefaultDirectionMask,
3755 0, NULL, NULL, NULL,
3756 out_size, &out_read, &out_len,
3757 out_buf);
3758 if (err == noErr && out_read < length * sizeof (UniChar))
3759 {
3760 xfree (out_buf);
3761 out_size += length;
3762 }
3763 else
3764 break;
3765 }
3766 if (err == noErr)
3767 result = CFStringCreateWithCharacters (NULL, out_buf,
3768 out_len / sizeof (UniChar));
3769 if (uni)
3770 DisposeUnicodeToTextInfo (&uni);
3771 if (out_buf)
3772 xfree (out_buf);
3773 if (buffer)
3774 xfree (buffer);
3775 }
3776 else
3777 {
3778 result = str;
3779 CFRetain (result);
3780 }
3781
3782 return result;
3783}
3784#endif
3785
3786DEFUN ("mac-code-convert-string", Fmac_code_convert_string, Smac_code_convert_string, 3, 4, 0,
3787 doc: /* Convert STRING from SOURCE encoding to TARGET encoding.
3788The conversion is performed using the converter provided by the system.
3789Each encoding is specified by either a coding system symbol, a mime
3790charset string, or an integer as a CFStringEncoding value.
3791On Mac OS X 10.2 and later, you can do Unicode Normalization by
3792specifying the optional argument NORMALIZATION-FORM with a symbol NFD,
3793NFKD, NFC, NFKC, HFS+D, or HFS+C.
3794On successful conversion, returns the result string, else returns
3795nil. */)
3796 (string, source, target, normalization_form)
3797 Lisp_Object string, source, target, normalization_form;
3798{
3799 Lisp_Object result = Qnil;
3800 CFStringEncoding src_encoding, tgt_encoding;
3801 CFStringRef str = NULL;
3802 CFDataRef data = NULL;
3803
3804 CHECK_STRING (string);
3805 if (!INTEGERP (source) && !STRINGP (source))
3806 CHECK_SYMBOL (source);
3807 if (!INTEGERP (target) && !STRINGP (target))
3808 CHECK_SYMBOL (target);
3809 CHECK_SYMBOL (normalization_form);
3810
3811 BLOCK_INPUT;
3812
3813 src_encoding = get_cfstring_encoding_from_lisp (source);
3814 tgt_encoding = get_cfstring_encoding_from_lisp (target);
3815
3816 string = string_make_unibyte (string);
3817 if (src_encoding != kCFStringEncodingInvalidId
3818 && tgt_encoding != kCFStringEncodingInvalidId)
3819 str = CFStringCreateWithBytes (NULL, SDATA (string), SBYTES (string),
3820 src_encoding, true);
3821#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
3822 if (str)
3823 {
3824 CFStringRef saved_str = str;
3825
3826 str = cfstring_create_normalized (saved_str, normalization_form);
3827 CFRelease (saved_str);
3828 }
3829#endif
3830 if (str)
3831 {
3832 data = CFStringCreateExternalRepresentation (NULL, str,
3833 tgt_encoding, '\0');
3834 CFRelease (str);
3835 }
3836 if (data)
3837 {
3838 result = cfdata_to_lisp (data);
3839 CFRelease (data);
3840 }
3841
3842 UNBLOCK_INPUT;
3843
3844 return result;
3845}
3795#endif /* TARGET_API_MAC_CARBON */ 3846#endif /* TARGET_API_MAC_CARBON */
3796 3847
3797 3848
@@ -4232,9 +4283,6 @@ mac_get_system_locale ()
4232void 4283void
4233syms_of_mac () 4284syms_of_mac ()
4234{ 4285{
4235 QCLIPBOARD = intern ("CLIPBOARD");
4236 staticpro (&QCLIPBOARD);
4237
4238#if TARGET_API_MAC_CARBON 4286#if TARGET_API_MAC_CARBON
4239 Qstring = intern ("string"); staticpro (&Qstring); 4287 Qstring = intern ("string"); staticpro (&Qstring);
4240 Qnumber = intern ("number"); staticpro (&Qnumber); 4288 Qnumber = intern ("number"); staticpro (&Qnumber);
@@ -4246,13 +4294,21 @@ syms_of_mac ()
4246 4294
4247 Qxml = intern ("xml"); 4295 Qxml = intern ("xml");
4248 staticpro (&Qxml); 4296 staticpro (&Qxml);
4297
4298 Qmime_charset = intern ("mime-charset");
4299 staticpro (&Qmime_charset);
4300
4301 QNFD = intern ("NFD"); staticpro (&QNFD);
4302 QNFKD = intern ("NFKD"); staticpro (&QNFKD);
4303 QNFC = intern ("NFC"); staticpro (&QNFC);
4304 QNFKC = intern ("NFKC"); staticpro (&QNFKC);
4305 QHFS_plus_D = intern ("HFS+D"); staticpro (&QHFS_plus_D);
4306 QHFS_plus_C = intern ("HFS+C"); staticpro (&QHFS_plus_C);
4249#endif 4307#endif
4250 4308
4251 defsubr (&Smac_paste_function);
4252 defsubr (&Smac_cut_function);
4253 defsubr (&Sx_selection_exists_p);
4254#if TARGET_API_MAC_CARBON 4309#if TARGET_API_MAC_CARBON
4255 defsubr (&Smac_get_preference); 4310 defsubr (&Smac_get_preference);
4311 defsubr (&Smac_code_convert_string);
4256#endif 4312#endif
4257 defsubr (&Smac_clear_font_name_table); 4313 defsubr (&Smac_clear_font_name_table);
4258 4314