diff options
| author | YAMAMOTO Mitsuharu | 2005-12-10 01:49:44 +0000 |
|---|---|---|
| committer | YAMAMOTO Mitsuharu | 2005-12-10 01:49:44 +0000 |
| commit | 28714a27a112b8caa209894aa0a40329e7bbd586 (patch) | |
| tree | 808171a78d00a00d57212c1172cff9b2ba4c4906 /src/macselect.c | |
| parent | 31b6888a5c4dabd5df94947bb54b7ba9f0611a3b (diff) | |
| download | emacs-28714a27a112b8caa209894aa0a40329e7bbd586.tar.gz emacs-28714a27a112b8caa209894aa0a40329e7bbd586.zip | |
Include keymap.h.
(mac_ready_for_apple_events): New variable.
(Vmac_apple_event_map, Qmac_apple_event_class)
(Qmac_apple_event_id): New variables.
(syms_of_macselect): Initialize them.
(Qundefined, mac_store_apple_event): Add externs.
(struct apple_event_binding): New struct.
(find_event_binding_fun, find_event_binding)
(mac_find_apple_event_spec, defer_apple_events)
(mac_handle_apple_event, init_apple_event_handler)
(copy_scrap_flavor_data): New functions.
(Fmac_process_deferred_apple_events): New defun.
(syms_of_macselect): Defsubr it.
(mac_store_services_event): Fix extern.
(mac_handle_service_event): Don't allocate Lisp objects during
asynchronous input processing. Use mac_store_services_event
instead of mac_store_application_menu_event.
Diffstat (limited to 'src/macselect.c')
| -rw-r--r-- | src/macselect.c | 493 |
1 files changed, 411 insertions, 82 deletions
diff --git a/src/macselect.c b/src/macselect.c index 63221ba3a90..dd9603f8321 100644 --- a/src/macselect.c +++ b/src/macselect.c | |||
| @@ -23,6 +23,7 @@ Boston, MA 02110-1301, USA. */ | |||
| 23 | #include "lisp.h" | 23 | #include "lisp.h" |
| 24 | #include "macterm.h" | 24 | #include "macterm.h" |
| 25 | #include "blockinput.h" | 25 | #include "blockinput.h" |
| 26 | #include "keymap.h" | ||
| 26 | 27 | ||
| 27 | #if !TARGET_API_MAC_CARBON | 28 | #if !TARGET_API_MAC_CARBON |
| 28 | #include <Endian.h> | 29 | #include <Endian.h> |
| @@ -908,6 +909,253 @@ and t is the same as `SECONDARY'. */) | |||
| 908 | } | 909 | } |
| 909 | 910 | ||
| 910 | 911 | ||
| 912 | int mac_ready_for_apple_events = 0; | ||
| 913 | static Lisp_Object Vmac_apple_event_map; | ||
| 914 | static Lisp_Object Qmac_apple_event_class, Qmac_apple_event_id; | ||
| 915 | static struct | ||
| 916 | { | ||
| 917 | AppleEvent *buf; | ||
| 918 | int size, count; | ||
| 919 | } deferred_apple_events; | ||
| 920 | extern Lisp_Object Qundefined; | ||
| 921 | extern OSErr mac_store_apple_event P_ ((Lisp_Object, Lisp_Object, | ||
| 922 | const AEDesc *)); | ||
| 923 | |||
| 924 | struct apple_event_binding | ||
| 925 | { | ||
| 926 | UInt32 code; /* Apple event class or ID. */ | ||
| 927 | Lisp_Object key, binding; | ||
| 928 | }; | ||
| 929 | |||
| 930 | static void | ||
| 931 | find_event_binding_fun (key, binding, args, data) | ||
| 932 | Lisp_Object key, binding, args; | ||
| 933 | void *data; | ||
| 934 | { | ||
| 935 | struct apple_event_binding *event_binding = | ||
| 936 | (struct apple_event_binding *)data; | ||
| 937 | Lisp_Object code_string; | ||
| 938 | |||
| 939 | if (!SYMBOLP (key)) | ||
| 940 | return; | ||
| 941 | code_string = Fget (key, args); | ||
| 942 | if (STRINGP (code_string) && SBYTES (code_string) == 4 | ||
| 943 | && (EndianU32_BtoN (*((UInt32 *) SDATA (code_string))) | ||
| 944 | == event_binding->code)) | ||
| 945 | { | ||
| 946 | event_binding->key = key; | ||
| 947 | event_binding->binding = binding; | ||
| 948 | } | ||
| 949 | } | ||
| 950 | |||
| 951 | static void | ||
| 952 | find_event_binding (keymap, event_binding, class_p) | ||
| 953 | Lisp_Object keymap; | ||
| 954 | struct apple_event_binding *event_binding; | ||
| 955 | int class_p; | ||
| 956 | { | ||
| 957 | if (event_binding->code == 0) | ||
| 958 | event_binding->binding = | ||
| 959 | access_keymap (keymap, event_binding->key, 0, 1, 0); | ||
| 960 | else | ||
| 961 | { | ||
| 962 | event_binding->binding = Qnil; | ||
| 963 | map_keymap (keymap, find_event_binding_fun, | ||
| 964 | class_p ? Qmac_apple_event_class : Qmac_apple_event_id, | ||
| 965 | event_binding, 0); | ||
| 966 | } | ||
| 967 | } | ||
| 968 | |||
| 969 | void | ||
| 970 | mac_find_apple_event_spec (class, id, class_key, id_key, binding) | ||
| 971 | AEEventClass class; | ||
| 972 | AEEventID id; | ||
| 973 | Lisp_Object *class_key, *id_key, *binding; | ||
| 974 | { | ||
| 975 | struct apple_event_binding event_binding; | ||
| 976 | Lisp_Object keymap; | ||
| 977 | |||
| 978 | *binding = Qnil; | ||
| 979 | |||
| 980 | keymap = get_keymap (Vmac_apple_event_map, 0, 0); | ||
| 981 | if (NILP (keymap)) | ||
| 982 | return; | ||
| 983 | |||
| 984 | event_binding.code = class; | ||
| 985 | event_binding.key = *class_key; | ||
| 986 | event_binding.binding = Qnil; | ||
| 987 | find_event_binding (keymap, &event_binding, 1); | ||
| 988 | *class_key = event_binding.key; | ||
| 989 | keymap = get_keymap (event_binding.binding, 0, 0); | ||
| 990 | if (NILP (keymap)) | ||
| 991 | return; | ||
| 992 | |||
| 993 | event_binding.code = id; | ||
| 994 | event_binding.key = *id_key; | ||
| 995 | event_binding.binding = Qnil; | ||
| 996 | find_event_binding (keymap, &event_binding, 0); | ||
| 997 | *id_key = event_binding.key; | ||
| 998 | *binding = event_binding.binding; | ||
| 999 | } | ||
| 1000 | |||
| 1001 | static OSErr | ||
| 1002 | defer_apple_events (apple_event, reply) | ||
| 1003 | const AppleEvent *apple_event, *reply; | ||
| 1004 | { | ||
| 1005 | OSErr err; | ||
| 1006 | |||
| 1007 | err = AESuspendTheCurrentEvent (apple_event); | ||
| 1008 | |||
| 1009 | /* Mac OS 10.3 Xcode manual says AESuspendTheCurrentEvent makes | ||
| 1010 | copies of the Apple event and the reply, but Mac OS 10.4 Xcode | ||
| 1011 | manual says it doesn't. Anyway we create copies of them and save | ||
| 1012 | it in `deferred_apple_events'. */ | ||
| 1013 | if (err == noErr) | ||
| 1014 | { | ||
| 1015 | if (deferred_apple_events.buf == NULL) | ||
| 1016 | { | ||
| 1017 | deferred_apple_events.size = 16; | ||
| 1018 | deferred_apple_events.count = 0; | ||
| 1019 | deferred_apple_events.buf = | ||
| 1020 | xmalloc (sizeof (AppleEvent) * deferred_apple_events.size); | ||
| 1021 | if (deferred_apple_events.buf == NULL) | ||
| 1022 | err = memFullErr; | ||
| 1023 | } | ||
| 1024 | else if (deferred_apple_events.count == deferred_apple_events.size) | ||
| 1025 | { | ||
| 1026 | AppleEvent *newbuf; | ||
| 1027 | |||
| 1028 | deferred_apple_events.size *= 2; | ||
| 1029 | newbuf = xrealloc (deferred_apple_events.buf, | ||
| 1030 | sizeof (AppleEvent) * deferred_apple_events.size); | ||
| 1031 | if (newbuf) | ||
| 1032 | deferred_apple_events.buf = newbuf; | ||
| 1033 | else | ||
| 1034 | err = memFullErr; | ||
| 1035 | } | ||
| 1036 | } | ||
| 1037 | |||
| 1038 | if (err == noErr) | ||
| 1039 | { | ||
| 1040 | int count = deferred_apple_events.count; | ||
| 1041 | |||
| 1042 | AEDuplicateDesc (apple_event, deferred_apple_events.buf + count); | ||
| 1043 | AEDuplicateDesc (reply, deferred_apple_events.buf + count + 1); | ||
| 1044 | deferred_apple_events.count += 2; | ||
| 1045 | } | ||
| 1046 | |||
| 1047 | return err; | ||
| 1048 | } | ||
| 1049 | |||
| 1050 | static pascal OSErr | ||
| 1051 | mac_handle_apple_event (apple_event, reply, refcon) | ||
| 1052 | const AppleEvent *apple_event; | ||
| 1053 | AppleEvent *reply; | ||
| 1054 | SInt32 refcon; | ||
| 1055 | { | ||
| 1056 | OSErr err; | ||
| 1057 | AEEventClass event_class; | ||
| 1058 | AEEventID event_id; | ||
| 1059 | Lisp_Object class_key, id_key, binding; | ||
| 1060 | |||
| 1061 | /* We can't handle an Apple event that requests a reply, but this | ||
| 1062 | seems to be too restrictive. */ | ||
| 1063 | #if 0 | ||
| 1064 | if (reply->descriptorType != typeNull) | ||
| 1065 | return errAEEventNotHandled; | ||
| 1066 | #endif | ||
| 1067 | |||
| 1068 | if (!mac_ready_for_apple_events) | ||
| 1069 | { | ||
| 1070 | err = defer_apple_events (apple_event, reply); | ||
| 1071 | if (err != noErr) | ||
| 1072 | return errAEEventNotHandled; | ||
| 1073 | return noErr; | ||
| 1074 | } | ||
| 1075 | |||
| 1076 | err = AEGetAttributePtr (apple_event, keyEventClassAttr, typeType, NULL, | ||
| 1077 | &event_class, sizeof (AEEventClass), NULL); | ||
| 1078 | if (err == noErr) | ||
| 1079 | err = AEGetAttributePtr (apple_event, keyEventIDAttr, typeType, NULL, | ||
| 1080 | &event_id, sizeof (AEEventID), NULL); | ||
| 1081 | if (err == noErr) | ||
| 1082 | { | ||
| 1083 | mac_find_apple_event_spec (event_class, event_id, | ||
| 1084 | &class_key, &id_key, &binding); | ||
| 1085 | if (!NILP (binding) && !EQ (binding, Qundefined)) | ||
| 1086 | { | ||
| 1087 | if (INTEGERP (binding)) | ||
| 1088 | return XINT (binding); | ||
| 1089 | err = mac_store_apple_event (class_key, id_key, apple_event); | ||
| 1090 | if (err == noErr) | ||
| 1091 | return noErr; | ||
| 1092 | } | ||
| 1093 | } | ||
| 1094 | return errAEEventNotHandled; | ||
| 1095 | } | ||
| 1096 | |||
| 1097 | void | ||
| 1098 | init_apple_event_handler () | ||
| 1099 | { | ||
| 1100 | OSErr err; | ||
| 1101 | long result; | ||
| 1102 | |||
| 1103 | /* Make sure we have Apple events before starting. */ | ||
| 1104 | err = Gestalt (gestaltAppleEventsAttr, &result); | ||
| 1105 | if (err != noErr) | ||
| 1106 | abort (); | ||
| 1107 | |||
| 1108 | if (!(result & (1 << gestaltAppleEventsPresent))) | ||
| 1109 | abort (); | ||
| 1110 | |||
| 1111 | err = AEInstallEventHandler (typeWildCard, typeWildCard, | ||
| 1112 | #if TARGET_API_MAC_CARBON | ||
| 1113 | NewAEEventHandlerUPP (mac_handle_apple_event), | ||
| 1114 | #else | ||
| 1115 | NewAEEventHandlerProc (mac_handle_apple_event), | ||
| 1116 | #endif | ||
| 1117 | 0L, false); | ||
| 1118 | if (err != noErr) | ||
| 1119 | abort (); | ||
| 1120 | } | ||
| 1121 | |||
| 1122 | DEFUN ("mac-process-deferred-apple-events", Fmac_process_deferred_apple_events, Smac_process_deferred_apple_events, 0, 0, 0, | ||
| 1123 | doc: /* Process Apple events that are deferred at the startup time. */) | ||
| 1124 | () | ||
| 1125 | { | ||
| 1126 | OSErr err; | ||
| 1127 | Lisp_Object result = Qnil; | ||
| 1128 | long i, count; | ||
| 1129 | AppleEvent apple_event, reply; | ||
| 1130 | AEKeyword keyword; | ||
| 1131 | |||
| 1132 | if (mac_ready_for_apple_events) | ||
| 1133 | return Qnil; | ||
| 1134 | |||
| 1135 | BLOCK_INPUT; | ||
| 1136 | mac_ready_for_apple_events = 1; | ||
| 1137 | if (deferred_apple_events.buf) | ||
| 1138 | { | ||
| 1139 | for (i = 0; i < deferred_apple_events.count; i += 2) | ||
| 1140 | { | ||
| 1141 | AEResumeTheCurrentEvent (deferred_apple_events.buf + i, | ||
| 1142 | deferred_apple_events.buf + i + 1, | ||
| 1143 | ((AEEventHandlerUPP) | ||
| 1144 | kAEUseStandardDispatch), 0); | ||
| 1145 | AEDisposeDesc (deferred_apple_events.buf + i); | ||
| 1146 | AEDisposeDesc (deferred_apple_events.buf + i + 1); | ||
| 1147 | } | ||
| 1148 | xfree (deferred_apple_events.buf); | ||
| 1149 | bzero (&deferred_apple_events, sizeof (deferred_apple_events)); | ||
| 1150 | |||
| 1151 | result = Qt; | ||
| 1152 | } | ||
| 1153 | UNBLOCK_INPUT; | ||
| 1154 | |||
| 1155 | return result; | ||
| 1156 | } | ||
| 1157 | |||
| 1158 | |||
| 911 | #ifdef MAC_OSX | 1159 | #ifdef MAC_OSX |
| 912 | void | 1160 | void |
| 913 | init_service_handler () | 1161 | init_service_handler () |
| @@ -920,7 +1168,56 @@ init_service_handler () | |||
| 920 | GetEventTypeCount (specs), specs, NULL, NULL); | 1168 | GetEventTypeCount (specs), specs, NULL, NULL); |
| 921 | } | 1169 | } |
| 922 | 1170 | ||
| 923 | extern void mac_store_services_event P_ ((EventRef)); | 1171 | extern OSErr mac_store_services_event P_ ((EventRef)); |
| 1172 | |||
| 1173 | static OSStatus | ||
| 1174 | copy_scrap_flavor_data (from_scrap, to_scrap, flavor_type) | ||
| 1175 | ScrapRef from_scrap, to_scrap; | ||
| 1176 | ScrapFlavorType flavor_type; | ||
| 1177 | { | ||
| 1178 | OSStatus err; | ||
| 1179 | Size size, size_allocated; | ||
| 1180 | char *buf = NULL; | ||
| 1181 | |||
| 1182 | err = GetScrapFlavorSize (from_scrap, flavor_type, &size); | ||
| 1183 | if (err == noErr) | ||
| 1184 | buf = xmalloc (size); | ||
| 1185 | while (buf) | ||
| 1186 | { | ||
| 1187 | size_allocated = size; | ||
| 1188 | err = GetScrapFlavorData (from_scrap, flavor_type, &size, buf); | ||
| 1189 | if (err != noErr) | ||
| 1190 | { | ||
| 1191 | xfree (buf); | ||
| 1192 | buf = NULL; | ||
| 1193 | } | ||
| 1194 | else if (size_allocated < size) | ||
| 1195 | { | ||
| 1196 | char *newbuf = xrealloc (buf, size); | ||
| 1197 | |||
| 1198 | if (newbuf) | ||
| 1199 | buf = newbuf; | ||
| 1200 | else | ||
| 1201 | { | ||
| 1202 | xfree (buf); | ||
| 1203 | buf = NULL; | ||
| 1204 | } | ||
| 1205 | } | ||
| 1206 | else | ||
| 1207 | break; | ||
| 1208 | } | ||
| 1209 | if (err == noErr) | ||
| 1210 | if (buf == NULL) | ||
| 1211 | err = memFullErr; | ||
| 1212 | else | ||
| 1213 | { | ||
| 1214 | err = PutScrapFlavor (to_scrap, flavor_type, kScrapFlavorMaskNone, | ||
| 1215 | size, buf); | ||
| 1216 | xfree (buf); | ||
| 1217 | } | ||
| 1218 | |||
| 1219 | return err; | ||
| 1220 | } | ||
| 924 | 1221 | ||
| 925 | static OSStatus | 1222 | static OSStatus |
| 926 | mac_handle_service_event (call_ref, event, data) | 1223 | mac_handle_service_event (call_ref, event, data) |
| @@ -929,7 +1226,12 @@ mac_handle_service_event (call_ref, event, data) | |||
| 929 | void *data; | 1226 | void *data; |
| 930 | { | 1227 | { |
| 931 | OSStatus err = noErr; | 1228 | OSStatus err = noErr; |
| 932 | ScrapRef cur_scrap; | 1229 | ScrapRef cur_scrap, specific_scrap; |
| 1230 | UInt32 event_kind = GetEventKind (event); | ||
| 1231 | CFMutableArrayRef copy_types, paste_types; | ||
| 1232 | CFStringRef type; | ||
| 1233 | Lisp_Object rest; | ||
| 1234 | ScrapFlavorType flavor_type; | ||
| 933 | 1235 | ||
| 934 | /* Check if Vmac_services_selection is a valid selection that has a | 1236 | /* Check if Vmac_services_selection is a valid selection that has a |
| 935 | corresponding scrap. */ | 1237 | corresponding scrap. */ |
| @@ -940,86 +1242,103 @@ mac_handle_service_event (call_ref, event, data) | |||
| 940 | if (!(err == noErr && cur_scrap)) | 1242 | if (!(err == noErr && cur_scrap)) |
| 941 | return eventNotHandledErr; | 1243 | return eventNotHandledErr; |
| 942 | 1244 | ||
| 943 | switch (GetEventKind (event)) | 1245 | switch (event_kind) |
| 944 | { | 1246 | { |
| 945 | case kEventServiceGetTypes: | 1247 | case kEventServiceGetTypes: |
| 946 | { | 1248 | /* Set paste types. */ |
| 947 | CFMutableArrayRef copy_types, paste_types; | 1249 | err = GetEventParameter (event, kEventParamServicePasteTypes, |
| 948 | CFStringRef type; | 1250 | typeCFMutableArrayRef, NULL, |
| 949 | Lisp_Object rest; | 1251 | sizeof (CFMutableArrayRef), NULL, |
| 950 | ScrapFlavorType flavor_type; | 1252 | &paste_types); |
| 951 | 1253 | if (err != noErr) | |
| 952 | /* Set paste types. */ | 1254 | break; |
| 953 | err = GetEventParameter (event, kEventParamServicePasteTypes, | 1255 | |
| 954 | typeCFMutableArrayRef, NULL, | 1256 | for (rest = Vselection_converter_alist; CONSP (rest); |
| 955 | sizeof (CFMutableArrayRef), NULL, | 1257 | rest = XCDR (rest)) |
| 956 | &paste_types); | 1258 | if (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest))) |
| 957 | if (err == noErr) | 1259 | && (flavor_type = |
| 958 | for (rest = Vselection_converter_alist; CONSP (rest); | 1260 | get_flavor_type_from_symbol (XCAR (XCAR (rest))))) |
| 959 | rest = XCDR (rest)) | 1261 | { |
| 960 | if (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest))) | 1262 | type = CreateTypeStringWithOSType (flavor_type); |
| 961 | && (flavor_type = | 1263 | if (type) |
| 962 | get_flavor_type_from_symbol (XCAR (XCAR (rest))))) | ||
| 963 | { | 1264 | { |
| 964 | type = CreateTypeStringWithOSType (flavor_type); | 1265 | CFArrayAppendValue (paste_types, type); |
| 965 | if (type) | 1266 | CFRelease (type); |
| 966 | { | ||
| 967 | CFArrayAppendValue (paste_types, type); | ||
| 968 | CFRelease (type); | ||
| 969 | } | ||
| 970 | } | 1267 | } |
| 1268 | } | ||
| 971 | 1269 | ||
| 972 | /* Set copy types. */ | 1270 | /* Set copy types. */ |
| 973 | err = GetEventParameter (event, kEventParamServiceCopyTypes, | 1271 | err = GetEventParameter (event, kEventParamServiceCopyTypes, |
| 974 | typeCFMutableArrayRef, NULL, | 1272 | typeCFMutableArrayRef, NULL, |
| 975 | sizeof (CFMutableArrayRef), NULL, | 1273 | sizeof (CFMutableArrayRef), NULL, |
| 976 | ©_types); | 1274 | ©_types); |
| 977 | if (err == noErr | 1275 | if (err != noErr) |
| 978 | && !NILP (Fx_selection_owner_p (Vmac_services_selection))) | 1276 | break; |
| 979 | for (rest = get_scrap_target_type_list (cur_scrap); | 1277 | |
| 980 | CONSP (rest) && SYMBOLP (XCAR (rest)); rest = XCDR (rest)) | 1278 | if (NILP (Fx_selection_owner_p (Vmac_services_selection))) |
| 981 | { | 1279 | break; |
| 982 | flavor_type = get_flavor_type_from_symbol (XCAR (rest)); | 1280 | else |
| 983 | if (flavor_type) | 1281 | goto copy_all_flavors; |
| 984 | { | ||
| 985 | type = CreateTypeStringWithOSType (flavor_type); | ||
| 986 | if (type) | ||
| 987 | { | ||
| 988 | CFArrayAppendValue (copy_types, type); | ||
| 989 | CFRelease (type); | ||
| 990 | } | ||
| 991 | } | ||
| 992 | } | ||
| 993 | } | ||
| 994 | break; | ||
| 995 | 1282 | ||
| 996 | case kEventServiceCopy: | 1283 | case kEventServiceCopy: |
| 997 | { | 1284 | err = GetEventParameter (event, kEventParamScrapRef, |
| 998 | ScrapRef specific_scrap; | 1285 | typeScrapRef, NULL, |
| 999 | Lisp_Object rest, data; | 1286 | sizeof (ScrapRef), NULL, &specific_scrap); |
| 1000 | 1287 | if (err != noErr | |
| 1001 | err = GetEventParameter (event, kEventParamScrapRef, | 1288 | || NILP (Fx_selection_owner_p (Vmac_services_selection))) |
| 1002 | typeScrapRef, NULL, | 1289 | { |
| 1003 | sizeof (ScrapRef), NULL, &specific_scrap); | ||
| 1004 | if (err == noErr | ||
| 1005 | && !NILP (Fx_selection_owner_p (Vmac_services_selection))) | ||
| 1006 | for (rest = get_scrap_target_type_list (cur_scrap); | ||
| 1007 | CONSP (rest) && SYMBOLP (XCAR (rest)); rest = XCDR (rest)) | ||
| 1008 | { | ||
| 1009 | data = get_scrap_string (cur_scrap, XCAR (rest)); | ||
| 1010 | if (STRINGP (data)) | ||
| 1011 | err = put_scrap_string (specific_scrap, XCAR (rest), data); | ||
| 1012 | } | ||
| 1013 | else | ||
| 1014 | err = eventNotHandledErr; | 1290 | err = eventNotHandledErr; |
| 1291 | break; | ||
| 1292 | } | ||
| 1293 | |||
| 1294 | copy_all_flavors: | ||
| 1295 | { | ||
| 1296 | UInt32 count, i; | ||
| 1297 | ScrapFlavorInfo *flavor_info = NULL; | ||
| 1298 | ScrapFlavorFlags flags; | ||
| 1299 | |||
| 1300 | err = GetScrapFlavorCount (cur_scrap, &count); | ||
| 1301 | if (err == noErr) | ||
| 1302 | flavor_info = xmalloc (sizeof (ScrapFlavorInfo) * count); | ||
| 1303 | if (flavor_info) | ||
| 1304 | { | ||
| 1305 | err = GetScrapFlavorInfoList (cur_scrap, &count, flavor_info); | ||
| 1306 | if (err != noErr) | ||
| 1307 | { | ||
| 1308 | xfree (flavor_info); | ||
| 1309 | flavor_info = NULL; | ||
| 1310 | } | ||
| 1311 | } | ||
| 1312 | if (flavor_info == NULL) | ||
| 1313 | break; | ||
| 1314 | |||
| 1315 | for (i = 0; i < count; i++) | ||
| 1316 | { | ||
| 1317 | flavor_type = flavor_info[i].flavorType; | ||
| 1318 | err = GetScrapFlavorFlags (cur_scrap, flavor_type, &flags); | ||
| 1319 | if (err == noErr && !(flags & kScrapFlavorMaskSenderOnly)) | ||
| 1320 | { | ||
| 1321 | if (event_kind == kEventServiceCopy) | ||
| 1322 | err = copy_scrap_flavor_data (cur_scrap, specific_scrap, | ||
| 1323 | flavor_type); | ||
| 1324 | else /* event_kind == kEventServiceGetTypes */ | ||
| 1325 | { | ||
| 1326 | type = CreateTypeStringWithOSType (flavor_type); | ||
| 1327 | if (type) | ||
| 1328 | { | ||
| 1329 | CFArrayAppendValue (copy_types, type); | ||
| 1330 | CFRelease (type); | ||
| 1331 | } | ||
| 1332 | } | ||
| 1333 | } | ||
| 1334 | } | ||
| 1335 | xfree (flavor_info); | ||
| 1015 | } | 1336 | } |
| 1016 | break; | 1337 | break; |
| 1017 | 1338 | ||
| 1018 | case kEventServicePaste: | 1339 | case kEventServicePaste: |
| 1019 | case kEventServicePerform: | 1340 | case kEventServicePerform: |
| 1020 | { | 1341 | { |
| 1021 | ScrapRef specific_scrap; | ||
| 1022 | Lisp_Object rest, data; | ||
| 1023 | int data_exists_p = 0; | 1342 | int data_exists_p = 0; |
| 1024 | 1343 | ||
| 1025 | err = GetEventParameter (event, kEventParamScrapRef, typeScrapRef, | 1344 | err = GetEventParameter (event, kEventParamScrapRef, typeScrapRef, |
| @@ -1033,25 +1352,24 @@ mac_handle_service_event (call_ref, event, data) | |||
| 1033 | { | 1352 | { |
| 1034 | if (! (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest))))) | 1353 | if (! (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest))))) |
| 1035 | continue; | 1354 | continue; |
| 1036 | data = get_scrap_string (specific_scrap, XCAR (XCAR (rest))); | 1355 | flavor_type = get_flavor_type_from_symbol (XCAR (XCAR (rest))); |
| 1037 | if (STRINGP (data)) | 1356 | if (flavor_type == 0) |
| 1038 | { | 1357 | continue; |
| 1039 | err = put_scrap_string (cur_scrap, XCAR (XCAR (rest)), | 1358 | err = copy_scrap_flavor_data (specific_scrap, cur_scrap, |
| 1040 | data); | 1359 | flavor_type); |
| 1041 | if (err != noErr) | 1360 | if (err == noErr) |
| 1042 | break; | 1361 | data_exists_p = 1; |
| 1043 | data_exists_p = 1; | ||
| 1044 | } | ||
| 1045 | } | 1362 | } |
| 1046 | if (err == noErr) | 1363 | if (!data_exists_p) |
| 1047 | if (data_exists_p) | 1364 | err = eventNotHandledErr; |
| 1048 | mac_store_application_menu_event (event); | 1365 | else |
| 1049 | else | 1366 | err = mac_store_services_event (event); |
| 1050 | err = eventNotHandledErr; | ||
| 1051 | } | 1367 | } |
| 1052 | break; | 1368 | break; |
| 1053 | } | 1369 | } |
| 1054 | 1370 | ||
| 1371 | if (err != noErr) | ||
| 1372 | err = eventNotHandledErr; | ||
| 1055 | return err; | 1373 | return err; |
| 1056 | } | 1374 | } |
| 1057 | #endif | 1375 | #endif |
| @@ -1065,6 +1383,7 @@ syms_of_macselect () | |||
| 1065 | defsubr (&Sx_disown_selection_internal); | 1383 | defsubr (&Sx_disown_selection_internal); |
| 1066 | defsubr (&Sx_selection_owner_p); | 1384 | defsubr (&Sx_selection_owner_p); |
| 1067 | defsubr (&Sx_selection_exists_p); | 1385 | defsubr (&Sx_selection_exists_p); |
| 1386 | defsubr (&Smac_process_deferred_apple_events); | ||
| 1068 | 1387 | ||
| 1069 | Vselection_alist = Qnil; | 1388 | Vselection_alist = Qnil; |
| 1070 | staticpro (&Vselection_alist); | 1389 | staticpro (&Vselection_alist); |
| @@ -1106,6 +1425,10 @@ next communication only. After the communication, this variable is | |||
| 1106 | set to nil. */); | 1425 | set to nil. */); |
| 1107 | Vnext_selection_coding_system = Qnil; | 1426 | Vnext_selection_coding_system = Qnil; |
| 1108 | 1427 | ||
| 1428 | DEFVAR_LISP ("mac-apple-event-map", &Vmac_apple_event_map, | ||
| 1429 | doc: /* Keymap for Apple events handled by Emacs. */); | ||
| 1430 | Vmac_apple_event_map = Fmake_sparse_keymap (Qnil); | ||
| 1431 | |||
| 1109 | #ifdef MAC_OSX | 1432 | #ifdef MAC_OSX |
| 1110 | DEFVAR_LISP ("mac-services-selection", &Vmac_services_selection, | 1433 | DEFVAR_LISP ("mac-services-selection", &Vmac_services_selection, |
| 1111 | doc: /* Selection name for communication via Services menu. */); | 1434 | doc: /* Selection name for communication via Services menu. */); |
| @@ -1125,6 +1448,12 @@ set to nil. */); | |||
| 1125 | 1448 | ||
| 1126 | Qmac_ostype = intern ("mac-ostype"); | 1449 | Qmac_ostype = intern ("mac-ostype"); |
| 1127 | staticpro (&Qmac_ostype); | 1450 | staticpro (&Qmac_ostype); |
| 1451 | |||
| 1452 | Qmac_apple_event_class = intern ("mac-apple-event-class"); | ||
| 1453 | staticpro (&Qmac_apple_event_class); | ||
| 1454 | |||
| 1455 | Qmac_apple_event_id = intern ("mac-apple-event-id"); | ||
| 1456 | staticpro (&Qmac_apple_event_id); | ||
| 1128 | } | 1457 | } |
| 1129 | 1458 | ||
| 1130 | /* arch-tag: f3c91ad8-99e0-4bd6-9eef-251b2f848732 | 1459 | /* arch-tag: f3c91ad8-99e0-4bd6-9eef-251b2f848732 |