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), &timestamp);
223 #else /* !TARGET_API_MAC_CARBON */
224 return PutScrap (sizeof (timestamp), SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP,
225 &timestamp);
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, &timestamp); 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)