Mercurial > emacs
comparison src/macselect.c @ 80391:1d3df1b9547b
[!TARGET_API_MAC_CARBON] Include Scrap.h.
[MAC_OSX] (install_service_handler): Rename from init_service_handler.
All callers changed. Return OSStatus value.
(Selection): New typedef. Use instead of ScrapRef.
(mac_get_selection_from_symbol): Rename from get_scrap_from_symbol.
(mac_valid_selection_target_p): Rename from valid_scrap_target_type_p.
(mac_clear_selection): Rename from clear_scrap.
(get_flavor_type_from_symbol): New argument SEL and subsume function of
scrap_has_target_type. All uses changed.
(mac_get_selection_ownership_info, mac_valid_selection_value_p)
(mac_selection_has_target_p): New functions.
(mac_put_selection_value): Rename from put_scrap_string.
(mac_get_selection_value): Rename from get_scrap_string.
(mac_get_selection_target_list): Rename from get_scrap_target_type_list.
(put_scrap_private_timestamp, scrap_has_target_type)
(get_scrap_private_timestamp): Remove functions.
(SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP): Remove define.
(x_own_selection, x_get_local_selection):
Use mac_valid_selection_value_p.
(x_own_selection): Don't use put_scrap_private_timestamp.
Record OWNERSHIP-INFO into Vselection_alist instead.
(x_get_local_selection): Don't check type if request is local.
(Fx_selection_owner_p): Don't use get_scrap_private_timestamp.
Detect ownership change with OWNERSHIP-INFO in Vselection_alist instead.
author | YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> |
---|---|
date | Sat, 29 Mar 2008 00:46:38 +0000 |
parents | fc2bcd2a8aad |
children | 98811b17d3b9 4e76a03232e5 |
comparison
equal
deleted
inserted
replaced
80390:59863894d837 | 80391:1d3df1b9547b |
---|---|
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 #include "keymap.h" |
27 | 27 |
28 #if !TARGET_API_MAC_CARBON | 28 #if TARGET_API_MAC_CARBON |
29 typedef ScrapRef Selection; | |
30 #else /* !TARGET_API_MAC_CARBON */ | |
31 #include <Scrap.h> | |
29 #include <Endian.h> | 32 #include <Endian.h> |
30 typedef int ScrapRef; | 33 typedef int Selection; |
31 typedef ResType ScrapFlavorType; | |
32 #endif /* !TARGET_API_MAC_CARBON */ | 34 #endif /* !TARGET_API_MAC_CARBON */ |
33 | 35 |
34 static OSStatus get_scrap_from_symbol P_ ((Lisp_Object, int, ScrapRef *)); | 36 static OSStatus mac_get_selection_from_symbol P_ ((Lisp_Object, int, |
35 static ScrapFlavorType get_flavor_type_from_symbol P_ ((Lisp_Object)); | 37 Selection *)); |
36 static int valid_scrap_target_type_p P_ ((Lisp_Object)); | 38 static ScrapFlavorType get_flavor_type_from_symbol P_ ((Lisp_Object, |
37 static OSStatus clear_scrap P_ ((ScrapRef *)); | 39 Selection)); |
38 static OSStatus put_scrap_string P_ ((ScrapRef, Lisp_Object, Lisp_Object)); | 40 static int mac_valid_selection_target_p P_ ((Lisp_Object)); |
39 static OSStatus put_scrap_private_timestamp P_ ((ScrapRef, unsigned long)); | 41 static OSStatus mac_clear_selection P_ ((Selection *)); |
40 static ScrapFlavorType scrap_has_target_type P_ ((ScrapRef, Lisp_Object)); | 42 static Lisp_Object mac_get_selection_ownership_info P_ ((Selection)); |
41 static Lisp_Object get_scrap_string P_ ((ScrapRef, Lisp_Object)); | 43 static int mac_valid_selection_value_p P_ ((Lisp_Object, Lisp_Object)); |
42 static OSStatus get_scrap_private_timestamp P_ ((ScrapRef, unsigned long *)); | 44 static OSStatus mac_put_selection_value P_ ((Selection, Lisp_Object, |
43 static Lisp_Object get_scrap_target_type_list P_ ((ScrapRef)); | 45 Lisp_Object)); |
46 static int mac_selection_has_target_p P_ ((Selection, Lisp_Object)); | |
47 static Lisp_Object mac_get_selection_value P_ ((Selection, Lisp_Object)); | |
48 static Lisp_Object mac_get_selection_target_list P_ ((Selection)); | |
44 static void x_own_selection P_ ((Lisp_Object, Lisp_Object)); | 49 static void x_own_selection P_ ((Lisp_Object, Lisp_Object)); |
45 static Lisp_Object x_get_local_selection P_ ((Lisp_Object, Lisp_Object, int)); | 50 static Lisp_Object x_get_local_selection P_ ((Lisp_Object, Lisp_Object, int)); |
46 static Lisp_Object x_get_foreign_selection P_ ((Lisp_Object, | 51 static Lisp_Object x_get_foreign_selection P_ ((Lisp_Object, |
47 Lisp_Object, | 52 Lisp_Object, |
48 Lisp_Object)); | 53 Lisp_Object)); |
54 #endif | 59 #endif |
55 | 60 |
56 Lisp_Object QPRIMARY, QSECONDARY, QTIMESTAMP, QTARGETS; | 61 Lisp_Object QPRIMARY, QSECONDARY, QTIMESTAMP, QTARGETS; |
57 | 62 |
58 static Lisp_Object Vx_lost_selection_functions; | 63 static Lisp_Object Vx_lost_selection_functions; |
59 /* Coding system for communicating with other programs via scrap. */ | 64 /* Coding system for communicating with other programs via selections. */ |
60 static Lisp_Object Vselection_coding_system; | 65 static Lisp_Object Vselection_coding_system; |
61 | 66 |
62 /* Coding system for the next communicating with other programs. */ | 67 /* Coding system for the next communicating with other programs. */ |
63 static Lisp_Object Vnext_selection_coding_system; | 68 static Lisp_Object Vnext_selection_coding_system; |
64 | 69 |
68 window server. */ | 73 window server. */ |
69 /* Defined in keyboard.c. */ | 74 /* Defined in keyboard.c. */ |
70 extern unsigned long last_event_timestamp; | 75 extern unsigned long last_event_timestamp; |
71 | 76 |
72 /* This is an association list whose elements are of the form | 77 /* This is an association list whose elements are of the form |
73 ( SELECTION-NAME SELECTION-VALUE SELECTION-TIMESTAMP FRAME) | 78 ( SELECTION-NAME SELECTION-VALUE SELECTION-TIMESTAMP FRAME OWNERSHIP-INFO) |
74 SELECTION-NAME is a lisp symbol. | 79 SELECTION-NAME is a lisp symbol. |
75 SELECTION-VALUE is the value that emacs owns for that selection. | 80 SELECTION-VALUE is the value that emacs owns for that selection. |
76 It may be any kind of Lisp object. | 81 It may be any kind of Lisp object. |
77 SELECTION-TIMESTAMP is the time at which emacs began owning this selection, | 82 SELECTION-TIMESTAMP is the time at which emacs began owning this selection, |
78 as a cons of two 16-bit numbers (making a 32 bit time.) | 83 as a cons of two 16-bit numbers (making a 32 bit time.) |
79 FRAME is the frame for which we made the selection. | 84 FRAME is the frame for which we made the selection. |
80 If there is an entry in this alist, and the data for the flavor | 85 OWNERSHIP-INFO is a value saved when emacs owns for that selection. |
81 type SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP in the corresponding scrap | 86 If another application takes the ownership of that selection |
82 (if exists) coincides with SELECTION-TIMESTAMP, then it can be | 87 later, then newly examined ownership info value should be |
83 assumed that Emacs owns that selection. | 88 different from the saved one. |
89 If there is an entry in this alist, the current ownership info for | |
90 the selection coincides with OWNERSHIP-INFO, then it can be | |
91 assumed that Emacs owns that selection. | |
84 The only (eq) parts of this list that are visible from Lisp are the | 92 The only (eq) parts of this list that are visible from Lisp are the |
85 selection-values. */ | 93 selection-values. */ |
86 static Lisp_Object Vselection_alist; | 94 static Lisp_Object Vselection_alist; |
87 | |
88 #define SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP 'Etsp' | |
89 | 95 |
90 /* This is an alist whose CARs are selection-types and whose CDRs are | 96 /* This is an alist whose CARs are selection-types and whose CDRs are |
91 the names of Lisp functions to call to convert the given Emacs | 97 the names of Lisp functions to call to convert the given Emacs |
92 selection value to a string representing the given selection type. | 98 selection value to a string representing the given selection type. |
93 This is for Lisp-level extension of the emacs selection | 99 This is for Lisp-level extension of the emacs selection |
102 #ifdef MAC_OSX | 108 #ifdef MAC_OSX |
103 /* Selection name for communication via Services menu. */ | 109 /* Selection name for communication via Services menu. */ |
104 static Lisp_Object Vmac_service_selection; | 110 static Lisp_Object Vmac_service_selection; |
105 #endif | 111 #endif |
106 | 112 |
107 /* Get a reference to the scrap corresponding to the symbol SYM. The | 113 /* Get a reference to the selection corresponding to the symbol SYM. |
108 reference is set to *SCRAP, and it becomes NULL if there's no | 114 The reference is set to *SEL, and it becomes NULL if there's no |
109 corresponding scrap. Clear the scrap if CLEAR_P is non-zero. */ | 115 corresponding selection. Clear the selection if CLEAR_P is |
116 non-zero. */ | |
110 | 117 |
111 static OSStatus | 118 static OSStatus |
112 get_scrap_from_symbol (sym, clear_p, scrap) | 119 mac_get_selection_from_symbol (sym, clear_p, sel) |
113 Lisp_Object sym; | 120 Lisp_Object sym; |
114 int clear_p; | 121 int clear_p; |
115 ScrapRef *scrap; | 122 Selection *sel; |
116 { | 123 { |
117 OSStatus err = noErr; | 124 OSStatus err = noErr; |
118 Lisp_Object str = Fget (sym, Qmac_scrap_name); | 125 Lisp_Object str = Fget (sym, Qmac_scrap_name); |
119 | 126 |
120 if (!STRINGP (str)) | 127 if (!STRINGP (str)) |
121 *scrap = NULL; | 128 *sel = NULL; |
122 else | 129 else |
123 { | 130 { |
124 #if TARGET_API_MAC_CARBON | 131 #if TARGET_API_MAC_CARBON |
125 #ifdef MAC_OSX | 132 #ifdef MAC_OSX |
126 CFStringRef scrap_name = cfstring_create_with_string (str); | 133 CFStringRef scrap_name = cfstring_create_with_string (str); |
127 OptionBits options = (clear_p ? kScrapClearNamedScrap | 134 OptionBits options = (clear_p ? kScrapClearNamedScrap |
128 : kScrapGetNamedScrap); | 135 : kScrapGetNamedScrap); |
129 | 136 |
130 err = GetScrapByName (scrap_name, options, scrap); | 137 err = GetScrapByName (scrap_name, options, sel); |
131 CFRelease (scrap_name); | 138 CFRelease (scrap_name); |
132 #else /* !MAC_OSX */ | 139 #else /* !MAC_OSX */ |
133 if (clear_p) | 140 if (clear_p) |
134 err = ClearCurrentScrap (); | 141 err = ClearCurrentScrap (); |
135 if (err == noErr) | 142 if (err == noErr) |
136 err = GetCurrentScrap (scrap); | 143 err = GetCurrentScrap (sel); |
137 #endif /* !MAC_OSX */ | 144 #endif /* !MAC_OSX */ |
138 #else /* !TARGET_API_MAC_CARBON */ | 145 #else /* !TARGET_API_MAC_CARBON */ |
139 if (clear_p) | 146 if (clear_p) |
140 err = ZeroScrap (); | 147 err = ZeroScrap (); |
141 if (err == noErr) | 148 if (err == noErr) |
142 *scrap = 1; | 149 *sel = 1; |
143 #endif /* !TARGET_API_MAC_CARBON */ | 150 #endif /* !TARGET_API_MAC_CARBON */ |
144 } | 151 } |
145 | 152 |
146 return err; | 153 return err; |
147 } | 154 } |
148 | 155 |
149 /* Get a scrap flavor type from the symbol SYM. Return 0 if no | 156 /* Get a scrap flavor type from the symbol SYM. Return 0 if no |
150 corresponding flavor type. */ | 157 corresponding flavor type. If SEL is non-zero, the return value is |
158 non-zero only when the SEL has the flavor type. */ | |
151 | 159 |
152 static ScrapFlavorType | 160 static ScrapFlavorType |
153 get_flavor_type_from_symbol (sym) | 161 get_flavor_type_from_symbol (sym, sel) |
154 Lisp_Object sym; | 162 Lisp_Object sym; |
163 Selection sel; | |
155 { | 164 { |
156 Lisp_Object str = Fget (sym, Qmac_ostype); | 165 Lisp_Object str = Fget (sym, Qmac_ostype); |
166 ScrapFlavorType flavor_type; | |
157 | 167 |
158 if (STRINGP (str) && SBYTES (str) == 4) | 168 if (STRINGP (str) && SBYTES (str) == 4) |
159 return EndianU32_BtoN (*((UInt32 *) SDATA (str))); | 169 flavor_type = EndianU32_BtoN (*((UInt32 *) SDATA (str))); |
160 | 170 else |
161 return 0; | 171 flavor_type = 0; |
162 } | 172 |
163 | 173 if (flavor_type && sel) |
164 /* Check if the symbol SYM has a corresponding scrap flavor type. */ | 174 { |
175 #if TARGET_API_MAC_CARBON | |
176 OSStatus err; | |
177 ScrapFlavorFlags flags; | |
178 | |
179 err = GetScrapFlavorFlags (sel, flavor_type, &flags); | |
180 if (err != noErr) | |
181 flavor_type = 0; | |
182 #else /* !TARGET_API_MAC_CARBON */ | |
183 SInt32 size, offset; | |
184 | |
185 size = GetScrap (NULL, flavor_type, &offset); | |
186 if (size < 0) | |
187 flavor_type = 0; | |
188 #endif /* !TARGET_API_MAC_CARBON */ | |
189 } | |
190 | |
191 return flavor_type; | |
192 } | |
193 | |
194 /* Check if the symbol SYM has a corresponding selection target type. */ | |
165 | 195 |
166 static int | 196 static int |
167 valid_scrap_target_type_p (sym) | 197 mac_valid_selection_target_p (sym) |
168 Lisp_Object sym; | 198 Lisp_Object sym; |
169 { | 199 { |
170 return get_flavor_type_from_symbol (sym) != 0; | 200 return get_flavor_type_from_symbol (sym, 0) != 0; |
171 } | 201 } |
172 | 202 |
173 /* Clear the scrap whose reference is *SCRAP. */ | 203 /* Clear the selection whose reference is *SEL. */ |
174 | 204 |
175 static INLINE OSStatus | 205 static OSStatus |
176 clear_scrap (scrap) | 206 mac_clear_selection (sel) |
177 ScrapRef *scrap; | 207 Selection *sel; |
178 { | 208 { |
179 #if TARGET_API_MAC_CARBON | 209 #if TARGET_API_MAC_CARBON |
180 #ifdef MAC_OSX | 210 #ifdef MAC_OSX |
181 return ClearScrap (scrap); | 211 return ClearScrap (sel); |
182 #else | 212 #else |
183 return ClearCurrentScrap (); | 213 OSStatus err; |
214 | |
215 err = ClearCurrentScrap (); | |
216 if (err == noErr) | |
217 err = GetCurrentScrap (sel); | |
218 return err; | |
184 #endif | 219 #endif |
185 #else /* !TARGET_API_MAC_CARBON */ | 220 #else /* !TARGET_API_MAC_CARBON */ |
186 return ZeroScrap (); | 221 return ZeroScrap (); |
187 #endif /* !TARGET_API_MAC_CARBON */ | 222 #endif /* !TARGET_API_MAC_CARBON */ |
188 } | 223 } |
189 | 224 |
190 /* Put Lisp String STR to the scrap SCRAP. The target type is | 225 /* Get ownership information for SEL. Emacs can detect a change of |
191 specified by TYPE. */ | 226 the ownership by comparing saved and current values of the |
227 ownership information. */ | |
228 | |
229 static Lisp_Object | |
230 mac_get_selection_ownership_info (sel) | |
231 Selection sel; | |
232 { | |
233 #if TARGET_API_MAC_CARBON | |
234 return long_to_cons ((unsigned long) sel); | |
235 #else /* !TARGET_API_MAC_CARBON */ | |
236 ScrapStuffPtr scrap_info = InfoScrap (); | |
237 | |
238 return make_number (scrap_info->scrapCount); | |
239 #endif /* !TARGET_API_MAC_CARBON */ | |
240 } | |
241 | |
242 /* Return non-zero if VALUE is a valid selection value for TARGET. */ | |
243 | |
244 static int | |
245 mac_valid_selection_value_p (value, target) | |
246 Lisp_Object value, target; | |
247 { | |
248 return STRINGP (value); | |
249 } | |
250 | |
251 /* Put Lisp Object VALUE to the selection SEL. The target type is | |
252 specified by TARGET. */ | |
192 | 253 |
193 static OSStatus | 254 static OSStatus |
194 put_scrap_string (scrap, type, str) | 255 mac_put_selection_value (sel, target, value) |
195 ScrapRef scrap; | 256 Selection sel; |
196 Lisp_Object type, str; | 257 Lisp_Object target, value; |
197 { | 258 { |
198 ScrapFlavorType flavor_type = get_flavor_type_from_symbol (type); | 259 ScrapFlavorType flavor_type = get_flavor_type_from_symbol (target, 0); |
199 | 260 |
200 if (flavor_type == 0) | 261 if (flavor_type == 0 || !STRINGP (value)) |
201 return noTypeErr; | 262 return noTypeErr; |
202 | 263 |
203 #if TARGET_API_MAC_CARBON | 264 #if TARGET_API_MAC_CARBON |
204 return PutScrapFlavor (scrap, flavor_type, kScrapFlavorMaskNone, | 265 return PutScrapFlavor (sel, flavor_type, kScrapFlavorMaskNone, |
205 SBYTES (str), SDATA (str)); | 266 SBYTES (value), SDATA (value)); |
206 #else /* !TARGET_API_MAC_CARBON */ | 267 #else /* !TARGET_API_MAC_CARBON */ |
207 return PutScrap (SBYTES (str), flavor_type, SDATA (str)); | 268 return PutScrap (SBYTES (value), flavor_type, SDATA (value)); |
208 #endif /* !TARGET_API_MAC_CARBON */ | 269 #endif /* !TARGET_API_MAC_CARBON */ |
209 } | 270 } |
210 | 271 |
211 /* Put TIMESTAMP to the scrap SCRAP. The timestamp is used for | 272 /* Check if data for the target type TARGET is available in SEL. */ |
212 checking if the scrap is owned by the process. */ | 273 |
213 | 274 static int |
214 static INLINE OSStatus | 275 mac_selection_has_target_p (sel, target) |
215 put_scrap_private_timestamp (scrap, timestamp) | 276 Selection sel; |
216 ScrapRef scrap; | 277 Lisp_Object target; |
217 unsigned long timestamp; | 278 { |
218 { | 279 return get_flavor_type_from_symbol (target, sel) != 0; |
219 #if TARGET_API_MAC_CARBON | 280 } |
220 return PutScrapFlavor (scrap, SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP, | 281 |
221 kScrapFlavorMaskSenderOnly, | 282 /* Get data for the target type TARGET from SEL and create a Lisp |
222 sizeof (timestamp), ×tamp); | |
223 #else /* !TARGET_API_MAC_CARBON */ | |
224 return PutScrap (sizeof (timestamp), SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP, | |
225 ×tamp); | |
226 #endif /* !TARGET_API_MAC_CARBON */ | |
227 } | |
228 | |
229 /* Check if data for the target type TYPE is available in SCRAP. */ | |
230 | |
231 static ScrapFlavorType | |
232 scrap_has_target_type (scrap, type) | |
233 ScrapRef scrap; | |
234 Lisp_Object type; | |
235 { | |
236 OSStatus err; | |
237 ScrapFlavorType flavor_type = get_flavor_type_from_symbol (type); | |
238 | |
239 if (flavor_type) | |
240 { | |
241 #if TARGET_API_MAC_CARBON | |
242 ScrapFlavorFlags flags; | |
243 | |
244 err = GetScrapFlavorFlags (scrap, flavor_type, &flags); | |
245 if (err != noErr) | |
246 flavor_type = 0; | |
247 #else /* !TARGET_API_MAC_CARBON */ | |
248 SInt32 size, offset; | |
249 | |
250 size = GetScrap (NULL, flavor_type, &offset); | |
251 if (size < 0) | |
252 flavor_type = 0; | |
253 #endif /* !TARGET_API_MAC_CARBON */ | |
254 } | |
255 | |
256 return flavor_type; | |
257 } | |
258 | |
259 /* Get data for the target type TYPE from SCRAP and create a Lisp | |
260 string. Return nil if failed to get data. */ | 283 string. Return nil if failed to get data. */ |
261 | 284 |
262 static Lisp_Object | 285 static Lisp_Object |
263 get_scrap_string (scrap, type) | 286 mac_get_selection_value (sel, target) |
264 ScrapRef scrap; | 287 Selection sel; |
265 Lisp_Object type; | 288 Lisp_Object target; |
266 { | 289 { |
267 OSStatus err; | 290 OSStatus err; |
268 Lisp_Object result = Qnil; | 291 Lisp_Object result = Qnil; |
269 ScrapFlavorType flavor_type = get_flavor_type_from_symbol (type); | 292 ScrapFlavorType flavor_type = get_flavor_type_from_symbol (target, sel); |
270 #if TARGET_API_MAC_CARBON | 293 #if TARGET_API_MAC_CARBON |
271 Size size; | 294 Size size; |
272 | 295 |
273 if (flavor_type) | 296 if (flavor_type) |
274 { | 297 { |
275 err = GetScrapFlavorSize (scrap, flavor_type, &size); | 298 err = GetScrapFlavorSize (sel, flavor_type, &size); |
276 if (err == noErr) | 299 if (err == noErr) |
277 { | 300 { |
278 do | 301 do |
279 { | 302 { |
280 result = make_uninit_string (size); | 303 result = make_uninit_string (size); |
281 err = GetScrapFlavorData (scrap, flavor_type, | 304 err = GetScrapFlavorData (sel, flavor_type, |
282 &size, SDATA (result)); | 305 &size, SDATA (result)); |
283 if (err != noErr) | 306 if (err != noErr) |
284 result = Qnil; | 307 result = Qnil; |
285 else if (size < SBYTES (result)) | 308 else if (size < SBYTES (result)) |
286 result = make_unibyte_string (SDATA (result), size); | 309 result = make_unibyte_string (SDATA (result), size); |
306 #endif | 329 #endif |
307 | 330 |
308 return result; | 331 return result; |
309 } | 332 } |
310 | 333 |
311 /* Get timestamp from the scrap SCRAP and set to *TIMPSTAMP. */ | 334 /* Get the list of target types in SEL. The return value is a list of |
312 | 335 target type symbols possibly followed by scrap flavor type |
313 static OSStatus | |
314 get_scrap_private_timestamp (scrap, timestamp) | |
315 ScrapRef scrap; | |
316 unsigned long *timestamp; | |
317 { | |
318 OSStatus err = noErr; | |
319 #if TARGET_API_MAC_CARBON | |
320 ScrapFlavorFlags flags; | |
321 | |
322 err = GetScrapFlavorFlags (scrap, SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP, &flags); | |
323 if (err == noErr) | |
324 { | |
325 if (!(flags & kScrapFlavorMaskSenderOnly)) | |
326 err = noTypeErr; | |
327 else | |
328 { | |
329 Size size = sizeof (*timestamp); | |
330 | |
331 err = GetScrapFlavorData (scrap, SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP, | |
332 &size, timestamp); | |
333 if (err == noErr && size != sizeof (*timestamp)) | |
334 err = noTypeErr; | |
335 } | |
336 } | |
337 #else /* !TARGET_API_MAC_CARBON */ | |
338 Handle handle; | |
339 SInt32 size, offset; | |
340 | |
341 size = GetScrap (NULL, SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP, &offset); | |
342 if (size == sizeof (*timestamp)) | |
343 { | |
344 handle = NewHandle (size); | |
345 HLock (handle); | |
346 size = GetScrap (handle, SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP, &offset); | |
347 if (size == sizeof (*timestamp)) | |
348 *timestamp = *((unsigned long *) *handle); | |
349 DisposeHandle (handle); | |
350 } | |
351 if (size != sizeof (*timestamp)) | |
352 err = noTypeErr; | |
353 #endif /* !TARGET_API_MAC_CARBON */ | |
354 | |
355 return err; | |
356 } | |
357 | |
358 /* Get the list of target types in SCRAP. The return value is a list | |
359 of target type symbols possibly followed by scrap flavor type | |
360 strings. */ | 336 strings. */ |
361 | 337 |
362 static Lisp_Object | 338 static Lisp_Object |
363 get_scrap_target_type_list (scrap) | 339 mac_get_selection_target_list (sel) |
364 ScrapRef scrap; | 340 Selection sel; |
365 { | 341 { |
366 Lisp_Object result = Qnil, rest, target_type; | 342 Lisp_Object result = Qnil, rest, target; |
367 #if TARGET_API_MAC_CARBON | 343 #if TARGET_API_MAC_CARBON |
368 OSStatus err; | 344 OSStatus err; |
369 UInt32 count, i, type; | 345 UInt32 count, i, type; |
370 ScrapFlavorInfo *flavor_info = NULL; | 346 ScrapFlavorInfo *flavor_info = NULL; |
371 Lisp_Object strings = Qnil; | 347 Lisp_Object strings = Qnil; |
372 | 348 |
373 err = GetScrapFlavorCount (scrap, &count); | 349 err = GetScrapFlavorCount (sel, &count); |
374 if (err == noErr) | 350 if (err == noErr) |
375 flavor_info = xmalloc (sizeof (ScrapFlavorInfo) * count); | 351 flavor_info = xmalloc (sizeof (ScrapFlavorInfo) * count); |
376 err = GetScrapFlavorInfoList (scrap, &count, flavor_info); | 352 err = GetScrapFlavorInfoList (sel, &count, flavor_info); |
377 if (err != noErr) | 353 if (err != noErr) |
378 { | 354 { |
379 xfree (flavor_info); | 355 xfree (flavor_info); |
380 flavor_info = NULL; | 356 flavor_info = NULL; |
381 } | 357 } |
385 for (rest = Vselection_converter_alist; CONSP (rest); rest = XCDR (rest)) | 361 for (rest = Vselection_converter_alist; CONSP (rest); rest = XCDR (rest)) |
386 { | 362 { |
387 ScrapFlavorType flavor_type = 0; | 363 ScrapFlavorType flavor_type = 0; |
388 | 364 |
389 if (CONSP (XCAR (rest)) | 365 if (CONSP (XCAR (rest)) |
390 && (target_type = XCAR (XCAR (rest)), | 366 && (target = XCAR (XCAR (rest)), |
391 SYMBOLP (target_type)) | 367 SYMBOLP (target)) |
392 && (flavor_type = scrap_has_target_type (scrap, target_type))) | 368 && (flavor_type = get_flavor_type_from_symbol (target, sel))) |
393 { | 369 { |
394 result = Fcons (target_type, result); | 370 result = Fcons (target, result); |
395 #if TARGET_API_MAC_CARBON | 371 #if TARGET_API_MAC_CARBON |
396 for (i = 0; i < count; i++) | 372 for (i = 0; i < count; i++) |
397 if (flavor_info[i].flavorType == flavor_type) | 373 if (flavor_info[i].flavorType == flavor_type) |
398 { | 374 { |
399 flavor_info[i].flavorType = 0; | 375 flavor_info[i].flavorType = 0; |
426 static void | 402 static void |
427 x_own_selection (selection_name, selection_value) | 403 x_own_selection (selection_name, selection_value) |
428 Lisp_Object selection_name, selection_value; | 404 Lisp_Object selection_name, selection_value; |
429 { | 405 { |
430 OSStatus err; | 406 OSStatus err; |
431 ScrapRef scrap; | 407 Selection sel; |
432 struct gcpro gcpro1, gcpro2; | 408 struct gcpro gcpro1, gcpro2; |
433 Lisp_Object rest, handler_fn, value, type; | 409 Lisp_Object rest, handler_fn, value, target_type; |
434 int count; | 410 int count; |
435 | 411 |
436 CHECK_SYMBOL (selection_name); | 412 CHECK_SYMBOL (selection_name); |
437 | 413 |
438 GCPRO2 (selection_name, selection_value); | 414 GCPRO2 (selection_name, selection_value); |
439 | 415 |
440 BLOCK_INPUT; | 416 BLOCK_INPUT; |
441 | 417 |
442 err = get_scrap_from_symbol (selection_name, 1, &scrap); | 418 err = mac_get_selection_from_symbol (selection_name, 1, &sel); |
443 if (err == noErr && scrap) | 419 if (err == noErr && sel) |
444 { | 420 { |
445 /* Don't allow a quit within the converter. | 421 /* Don't allow a quit within the converter. |
446 When the user types C-g, he would be surprised | 422 When the user types C-g, he would be surprised |
447 if by luck it came during a converter. */ | 423 if by luck it came during a converter. */ |
448 count = SPECPDL_INDEX (); | 424 count = SPECPDL_INDEX (); |
449 specbind (Qinhibit_quit, Qt); | 425 specbind (Qinhibit_quit, Qt); |
450 | 426 |
451 for (rest = Vselection_converter_alist; CONSP (rest); rest = XCDR (rest)) | 427 for (rest = Vselection_converter_alist; CONSP (rest); rest = XCDR (rest)) |
452 { | 428 { |
453 if (!(CONSP (XCAR (rest)) | 429 if (!(CONSP (XCAR (rest)) |
454 && (type = XCAR (XCAR (rest)), | 430 && (target_type = XCAR (XCAR (rest)), |
455 SYMBOLP (type)) | 431 SYMBOLP (target_type)) |
456 && valid_scrap_target_type_p (type) | 432 && mac_valid_selection_target_p (target_type) |
457 && (handler_fn = XCDR (XCAR (rest)), | 433 && (handler_fn = XCDR (XCAR (rest)), |
458 SYMBOLP (handler_fn)))) | 434 SYMBOLP (handler_fn)))) |
459 continue; | 435 continue; |
460 | 436 |
461 if (!NILP (handler_fn)) | 437 if (!NILP (handler_fn)) |
462 value = call3 (handler_fn, selection_name, | 438 value = call3 (handler_fn, selection_name, |
463 type, selection_value); | 439 target_type, selection_value); |
464 | 440 |
465 if (STRINGP (value)) | 441 if (NILP (value)) |
466 err = put_scrap_string (scrap, type, value); | 442 continue; |
443 | |
444 if (mac_valid_selection_value_p (value, target_type)) | |
445 err = mac_put_selection_value (sel, target_type, value); | |
467 else if (CONSP (value) | 446 else if (CONSP (value) |
468 && EQ (XCAR (value), type) | 447 && EQ (XCAR (value), target_type) |
469 && STRINGP (XCDR (value))) | 448 && mac_valid_selection_value_p (XCDR (value), target_type)) |
470 err = put_scrap_string (scrap, type, XCDR (value)); | 449 err = mac_put_selection_value (sel, target_type, XCDR (value)); |
471 } | 450 } |
472 | 451 |
473 unbind_to (count, Qnil); | 452 unbind_to (count, Qnil); |
474 | |
475 if (err == noErr) | |
476 err = put_scrap_private_timestamp (scrap, last_event_timestamp); | |
477 } | 453 } |
478 | 454 |
479 UNBLOCK_INPUT; | 455 UNBLOCK_INPUT; |
480 | 456 |
481 UNGCPRO; | 457 UNGCPRO; |
482 | 458 |
483 if (scrap && err != noErr) | 459 if (sel && err != noErr) |
484 error ("Can't set selection"); | 460 error ("Can't set selection"); |
485 | 461 |
486 /* Now update the local cache */ | 462 /* Now update the local cache */ |
487 { | 463 { |
488 Lisp_Object selection_time; | 464 Lisp_Object selection_time; |
489 Lisp_Object selection_data; | 465 Lisp_Object selection_data; |
466 Lisp_Object ownership_info; | |
490 Lisp_Object prev_value; | 467 Lisp_Object prev_value; |
491 | 468 |
492 selection_time = long_to_cons (last_event_timestamp); | 469 selection_time = long_to_cons (last_event_timestamp); |
470 if (sel) | |
471 { | |
472 BLOCK_INPUT; | |
473 ownership_info = mac_get_selection_ownership_info (sel); | |
474 UNBLOCK_INPUT; | |
475 } | |
476 else | |
477 ownership_info = Qnil; /* dummy value for local-only selection */ | |
493 selection_data = Fcons (selection_name, | 478 selection_data = Fcons (selection_name, |
494 Fcons (selection_value, | 479 Fcons (selection_value, |
495 Fcons (selection_time, | 480 Fcons (selection_time, |
496 Fcons (selected_frame, Qnil)))); | 481 Fcons (selected_frame, |
482 Fcons (ownership_info, | |
483 Qnil))))); | |
497 prev_value = assq_no_quit (selection_name, Vselection_alist); | 484 prev_value = assq_no_quit (selection_name, Vselection_alist); |
498 | 485 |
499 Vselection_alist = Fcons (selection_data, Vselection_alist); | 486 Vselection_alist = Fcons (selection_data, Vselection_alist); |
500 | 487 |
501 /* If we already owned the selection, remove the old selection data. | 488 /* If we already owned the selection, remove the old selection data. |
572 else | 559 else |
573 value = Qnil; | 560 value = Qnil; |
574 unbind_to (count, Qnil); | 561 unbind_to (count, Qnil); |
575 } | 562 } |
576 | 563 |
564 if (local_request) | |
565 return value; | |
566 | |
577 /* Make sure this value is of a type that we could transmit | 567 /* Make sure this value is of a type that we could transmit |
578 to another X client. */ | 568 to another application. */ |
579 | 569 |
570 type = target_type; | |
580 check = value; | 571 check = value; |
581 if (CONSP (value) | 572 if (CONSP (value) |
582 && SYMBOLP (XCAR (value))) | 573 && SYMBOLP (XCAR (value))) |
583 type = XCAR (value), | 574 type = XCAR (value), |
584 check = XCDR (value); | 575 check = XCDR (value); |
585 | 576 |
586 if (STRINGP (check) | 577 if (NILP (value) || mac_valid_selection_value_p (check, type)) |
587 || VECTORP (check) | |
588 || SYMBOLP (check) | |
589 || INTEGERP (check) | |
590 || NILP (value)) | |
591 return value; | |
592 /* Check for a value that cons_to_long could handle. */ | |
593 else if (CONSP (check) | |
594 && INTEGERP (XCAR (check)) | |
595 && (INTEGERP (XCDR (check)) | |
596 || | |
597 (CONSP (XCDR (check)) | |
598 && INTEGERP (XCAR (XCDR (check))) | |
599 && NILP (XCDR (XCDR (check)))))) | |
600 return value; | 578 return value; |
601 | 579 |
602 signal_error ("Invalid data returned by selection-conversion function", | 580 signal_error ("Invalid data returned by selection-conversion function", |
603 list2 (handler_fn, value)); | 581 list2 (handler_fn, value)); |
604 } | 582 } |
674 static Lisp_Object | 652 static Lisp_Object |
675 x_get_foreign_selection (selection_symbol, target_type, time_stamp) | 653 x_get_foreign_selection (selection_symbol, target_type, time_stamp) |
676 Lisp_Object selection_symbol, target_type, time_stamp; | 654 Lisp_Object selection_symbol, target_type, time_stamp; |
677 { | 655 { |
678 OSStatus err; | 656 OSStatus err; |
679 ScrapRef scrap; | 657 Selection sel; |
680 Lisp_Object result = Qnil; | 658 Lisp_Object result = Qnil; |
681 | 659 |
682 BLOCK_INPUT; | 660 BLOCK_INPUT; |
683 | 661 |
684 err = get_scrap_from_symbol (selection_symbol, 0, &scrap); | 662 err = mac_get_selection_from_symbol (selection_symbol, 0, &sel); |
685 if (err == noErr && scrap) | 663 if (err == noErr && sel) |
686 { | 664 { |
687 if (EQ (target_type, QTARGETS)) | 665 if (EQ (target_type, QTARGETS)) |
688 { | 666 { |
689 result = get_scrap_target_type_list (scrap); | 667 result = mac_get_selection_target_list (sel); |
690 result = Fvconcat (1, &result); | 668 result = Fvconcat (1, &result); |
691 } | 669 } |
692 else | 670 else |
693 { | 671 { |
694 result = get_scrap_string (scrap, target_type); | 672 result = mac_get_selection_value (sel, target_type); |
695 if (STRINGP (result)) | 673 if (STRINGP (result)) |
696 Fput_text_property (make_number (0), make_number (SBYTES (result)), | 674 Fput_text_property (make_number (0), make_number (SBYTES (result)), |
697 Qforeign_selection, target_type, result); | 675 Qforeign_selection, target_type, result); |
698 } | 676 } |
699 } | 677 } |
768 (selection, time) | 746 (selection, time) |
769 Lisp_Object selection; | 747 Lisp_Object selection; |
770 Lisp_Object time; | 748 Lisp_Object time; |
771 { | 749 { |
772 OSStatus err; | 750 OSStatus err; |
773 ScrapRef scrap; | 751 Selection sel; |
774 Lisp_Object local_selection_data; | 752 Lisp_Object local_selection_data; |
775 | 753 |
776 check_mac (); | 754 check_mac (); |
777 CHECK_SYMBOL (selection); | 755 CHECK_SYMBOL (selection); |
778 | 756 |
810 } | 788 } |
811 } | 789 } |
812 | 790 |
813 BLOCK_INPUT; | 791 BLOCK_INPUT; |
814 | 792 |
815 err = get_scrap_from_symbol (selection, 0, &scrap); | 793 err = mac_get_selection_from_symbol (selection, 0, &sel); |
816 if (err == noErr && scrap) | 794 if (err == noErr && sel) |
817 clear_scrap (&scrap); | 795 mac_clear_selection (&sel); |
818 | 796 |
819 UNBLOCK_INPUT; | 797 UNBLOCK_INPUT; |
820 | 798 |
821 return Qt; | 799 return Qt; |
822 } | 800 } |
831 and t is the same as `SECONDARY'. */) | 809 and t is the same as `SECONDARY'. */) |
832 (selection) | 810 (selection) |
833 Lisp_Object selection; | 811 Lisp_Object selection; |
834 { | 812 { |
835 OSStatus err; | 813 OSStatus err; |
836 ScrapRef scrap; | 814 Selection sel; |
837 Lisp_Object result = Qnil, local_selection_data; | 815 Lisp_Object result = Qnil, local_selection_data; |
838 | 816 |
839 check_mac (); | 817 check_mac (); |
840 CHECK_SYMBOL (selection); | 818 CHECK_SYMBOL (selection); |
841 if (EQ (selection, Qnil)) selection = QPRIMARY; | 819 if (EQ (selection, Qnil)) selection = QPRIMARY; |
846 if (NILP (local_selection_data)) | 824 if (NILP (local_selection_data)) |
847 return Qnil; | 825 return Qnil; |
848 | 826 |
849 BLOCK_INPUT; | 827 BLOCK_INPUT; |
850 | 828 |
851 err = get_scrap_from_symbol (selection, 0, &scrap); | 829 err = mac_get_selection_from_symbol (selection, 0, &sel); |
852 if (err == noErr && scrap) | 830 if (err == noErr && sel) |
853 { | 831 { |
854 unsigned long timestamp; | 832 Lisp_Object ownership_info; |
855 | 833 |
856 err = get_scrap_private_timestamp (scrap, ×tamp); | 834 ownership_info = XCAR (XCDR (XCDR (XCDR (XCDR (local_selection_data))))); |
857 if (err == noErr | 835 if (!NILP (Fequal (ownership_info, |
858 && (timestamp | 836 mac_get_selection_ownership_info (sel)))) |
859 == cons_to_long (XCAR (XCDR (XCDR (local_selection_data)))))) | |
860 result = Qt; | 837 result = Qt; |
861 } | 838 } |
862 else | 839 else |
863 result = Qt; | 840 result = Qt; |
864 | 841 |
876 and t is the same as `SECONDARY'. */) | 853 and t is the same as `SECONDARY'. */) |
877 (selection) | 854 (selection) |
878 Lisp_Object selection; | 855 Lisp_Object selection; |
879 { | 856 { |
880 OSStatus err; | 857 OSStatus err; |
881 ScrapRef scrap; | 858 Selection sel; |
882 Lisp_Object result = Qnil, rest; | 859 Lisp_Object result = Qnil, rest; |
883 | 860 |
884 /* It should be safe to call this before we have an Mac frame. */ | 861 /* It should be safe to call this before we have an Mac frame. */ |
885 if (! FRAME_MAC_P (SELECTED_FRAME ())) | 862 if (! FRAME_MAC_P (SELECTED_FRAME ())) |
886 return Qnil; | 863 return Qnil; |
891 if (EQ (selection, Qnil)) selection = QPRIMARY; | 868 if (EQ (selection, Qnil)) selection = QPRIMARY; |
892 if (EQ (selection, Qt)) selection = QSECONDARY; | 869 if (EQ (selection, Qt)) selection = QSECONDARY; |
893 | 870 |
894 BLOCK_INPUT; | 871 BLOCK_INPUT; |
895 | 872 |
896 err = get_scrap_from_symbol (selection, 0, &scrap); | 873 err = mac_get_selection_from_symbol (selection, 0, &sel); |
897 if (err == noErr && scrap) | 874 if (err == noErr && sel) |
898 for (rest = Vselection_converter_alist; CONSP (rest); rest = XCDR (rest)) | 875 for (rest = Vselection_converter_alist; CONSP (rest); rest = XCDR (rest)) |
899 { | 876 { |
900 if (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest))) | 877 if (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest))) |
901 && scrap_has_target_type (scrap, XCAR (XCAR (rest)))) | 878 && mac_selection_has_target_p (sel, XCAR (XCAR (rest)))) |
902 { | 879 { |
903 result = Qt; | 880 result = Qt; |
904 break; | 881 break; |
905 } | 882 } |
906 } | 883 } |
1621 | 1598 |
1622 /*********************************************************************** | 1599 /*********************************************************************** |
1623 Services menu support | 1600 Services menu support |
1624 ***********************************************************************/ | 1601 ***********************************************************************/ |
1625 #ifdef MAC_OSX | 1602 #ifdef MAC_OSX |
1626 void | 1603 OSStatus |
1627 init_service_handler () | 1604 install_service_handler () |
1628 { | 1605 { |
1629 static const EventTypeSpec specs[] = | 1606 static const EventTypeSpec specs[] = |
1630 {{kEventClassService, kEventServiceGetTypes}, | 1607 {{kEventClassService, kEventServiceGetTypes}, |
1631 {kEventClassService, kEventServiceCopy}, | 1608 {kEventClassService, kEventServiceCopy}, |
1632 {kEventClassService, kEventServicePaste}, | 1609 {kEventClassService, kEventServicePaste}, |
1633 {kEventClassService, kEventServicePerform}}; | 1610 {kEventClassService, kEventServicePerform}}; |
1634 InstallApplicationEventHandler (NewEventHandlerUPP (mac_handle_service_event), | 1611 |
1635 GetEventTypeCount (specs), specs, NULL, NULL); | 1612 return InstallApplicationEventHandler (NewEventHandlerUPP |
1613 (mac_handle_service_event), | |
1614 GetEventTypeCount (specs), | |
1615 specs, NULL, NULL); | |
1636 } | 1616 } |
1637 | 1617 |
1638 extern OSStatus mac_store_service_event P_ ((EventRef)); | 1618 extern OSStatus mac_store_service_event P_ ((EventRef)); |
1639 | 1619 |
1640 static OSStatus | 1620 static OSStatus |
1695 /* Check if Vmac_service_selection is a valid selection that has a | 1675 /* Check if Vmac_service_selection is a valid selection that has a |
1696 corresponding scrap. */ | 1676 corresponding scrap. */ |
1697 if (!SYMBOLP (Vmac_service_selection)) | 1677 if (!SYMBOLP (Vmac_service_selection)) |
1698 err = eventNotHandledErr; | 1678 err = eventNotHandledErr; |
1699 else | 1679 else |
1700 err = get_scrap_from_symbol (Vmac_service_selection, 0, &cur_scrap); | 1680 err = mac_get_selection_from_symbol (Vmac_service_selection, 0, &cur_scrap); |
1701 if (!(err == noErr && cur_scrap)) | 1681 if (!(err == noErr && cur_scrap)) |
1702 return eventNotHandledErr; | 1682 return eventNotHandledErr; |
1703 | 1683 |
1704 switch (event_kind) | 1684 switch (event_kind) |
1705 { | 1685 { |
1714 | 1694 |
1715 for (rest = Vselection_converter_alist; CONSP (rest); | 1695 for (rest = Vselection_converter_alist; CONSP (rest); |
1716 rest = XCDR (rest)) | 1696 rest = XCDR (rest)) |
1717 if (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest))) | 1697 if (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest))) |
1718 && (flavor_type = | 1698 && (flavor_type = |
1719 get_flavor_type_from_symbol (XCAR (XCAR (rest))))) | 1699 get_flavor_type_from_symbol (XCAR (XCAR (rest)), 0))) |
1720 { | 1700 { |
1721 type = CreateTypeStringWithOSType (flavor_type); | 1701 type = CreateTypeStringWithOSType (flavor_type); |
1722 if (type) | 1702 if (type) |
1723 { | 1703 { |
1724 CFArrayAppendValue (paste_types, type); | 1704 CFArrayAppendValue (paste_types, type); |
1799 | 1779 |
1800 err = GetEventParameter (event, kEventParamScrapRef, typeScrapRef, | 1780 err = GetEventParameter (event, kEventParamScrapRef, typeScrapRef, |
1801 NULL, sizeof (ScrapRef), NULL, | 1781 NULL, sizeof (ScrapRef), NULL, |
1802 &specific_scrap); | 1782 &specific_scrap); |
1803 if (err == noErr) | 1783 if (err == noErr) |
1804 err = clear_scrap (&cur_scrap); | 1784 err = mac_clear_selection (&cur_scrap); |
1805 if (err == noErr) | 1785 if (err == noErr) |
1806 for (rest = Vselection_converter_alist; CONSP (rest); | 1786 for (rest = Vselection_converter_alist; CONSP (rest); |
1807 rest = XCDR (rest)) | 1787 rest = XCDR (rest)) |
1808 { | 1788 { |
1809 if (! (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest))))) | 1789 if (! (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest))))) |
1810 continue; | 1790 continue; |
1811 flavor_type = get_flavor_type_from_symbol (XCAR (XCAR (rest))); | 1791 flavor_type = get_flavor_type_from_symbol (XCAR (XCAR (rest)), |
1792 specific_scrap); | |
1812 if (flavor_type == 0) | 1793 if (flavor_type == 0) |
1813 continue; | 1794 continue; |
1814 err = copy_scrap_flavor_data (specific_scrap, cur_scrap, | 1795 err = copy_scrap_flavor_data (specific_scrap, cur_scrap, |
1815 flavor_type); | 1796 flavor_type); |
1816 if (err == noErr) | 1797 if (err == noErr) |