aboutsummaryrefslogtreecommitdiffstats
path: root/src/macselect.c
diff options
context:
space:
mode:
authorYAMAMOTO Mitsuharu2008-03-29 00:46:38 +0000
committerYAMAMOTO Mitsuharu2008-03-29 00:46:38 +0000
commitc04e33a638db06b14497e6f6a667b1d49860a5ce (patch)
tree6d803e007317744387de89286cfd6d289c739bf4 /src/macselect.c
parentc98e277397009b29c62874aeadd153e480182a78 (diff)
downloademacs-c04e33a638db06b14497e6f6a667b1d49860a5ce.tar.gz
emacs-c04e33a638db06b14497e6f6a667b1d49860a5ce.zip
[!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.
Diffstat (limited to 'src/macselect.c')
-rw-r--r--src/macselect.c419
1 files changed, 200 insertions, 219 deletions
diff --git a/src/macselect.c b/src/macselect.c
index f624c02145b..56efd496945 100644
--- a/src/macselect.c
+++ b/src/macselect.c
@@ -25,22 +25,27 @@ Boston, MA 02110-1301, USA. */
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
29typedef ScrapRef Selection;
30#else /* !TARGET_API_MAC_CARBON */
31#include <Scrap.h>
29#include <Endian.h> 32#include <Endian.h>
30typedef int ScrapRef; 33typedef int Selection;
31typedef ResType ScrapFlavorType;
32#endif /* !TARGET_API_MAC_CARBON */ 34#endif /* !TARGET_API_MAC_CARBON */
33 35
34static OSStatus get_scrap_from_symbol P_ ((Lisp_Object, int, ScrapRef *)); 36static OSStatus mac_get_selection_from_symbol P_ ((Lisp_Object, int,
35static ScrapFlavorType get_flavor_type_from_symbol P_ ((Lisp_Object)); 37 Selection *));
36static int valid_scrap_target_type_p P_ ((Lisp_Object)); 38static ScrapFlavorType get_flavor_type_from_symbol P_ ((Lisp_Object,
37static OSStatus clear_scrap P_ ((ScrapRef *)); 39 Selection));
38static OSStatus put_scrap_string P_ ((ScrapRef, Lisp_Object, Lisp_Object)); 40static int mac_valid_selection_target_p P_ ((Lisp_Object));
39static OSStatus put_scrap_private_timestamp P_ ((ScrapRef, unsigned long)); 41static OSStatus mac_clear_selection P_ ((Selection *));
40static ScrapFlavorType scrap_has_target_type P_ ((ScrapRef, Lisp_Object)); 42static Lisp_Object mac_get_selection_ownership_info P_ ((Selection));
41static Lisp_Object get_scrap_string P_ ((ScrapRef, Lisp_Object)); 43static int mac_valid_selection_value_p P_ ((Lisp_Object, Lisp_Object));
42static OSStatus get_scrap_private_timestamp P_ ((ScrapRef, unsigned long *)); 44static OSStatus mac_put_selection_value P_ ((Selection, Lisp_Object,
43static Lisp_Object get_scrap_target_type_list P_ ((ScrapRef)); 45 Lisp_Object));
46static int mac_selection_has_target_p P_ ((Selection, Lisp_Object));
47static Lisp_Object mac_get_selection_value P_ ((Selection, Lisp_Object));
48static Lisp_Object mac_get_selection_target_list P_ ((Selection));
44static void x_own_selection P_ ((Lisp_Object, Lisp_Object)); 49static void x_own_selection P_ ((Lisp_Object, Lisp_Object));
45static Lisp_Object x_get_local_selection P_ ((Lisp_Object, Lisp_Object, int)); 50static Lisp_Object x_get_local_selection P_ ((Lisp_Object, Lisp_Object, int));
46static Lisp_Object x_get_foreign_selection P_ ((Lisp_Object, 51static Lisp_Object x_get_foreign_selection P_ ((Lisp_Object,
@@ -56,7 +61,7 @@ void init_service_handler P_ ((void));
56Lisp_Object QPRIMARY, QSECONDARY, QTIMESTAMP, QTARGETS; 61Lisp_Object QPRIMARY, QSECONDARY, QTIMESTAMP, QTARGETS;
57 62
58static Lisp_Object Vx_lost_selection_functions; 63static 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. */
60static Lisp_Object Vselection_coding_system; 65static 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. */
@@ -70,23 +75,24 @@ static Lisp_Object Qforeign_selection;
70extern unsigned long last_event_timestamp; 75extern 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. */
86static Lisp_Object Vselection_alist; 94static Lisp_Object Vselection_alist;
87 95
88#define SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP 'Etsp'
89
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.
@@ -104,21 +110,22 @@ static Lisp_Object Qmac_scrap_name, Qmac_ostype;
104static Lisp_Object Vmac_service_selection; 110static 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
111static OSStatus 118static OSStatus
112get_scrap_from_symbol (sym, clear_p, scrap) 119mac_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
@@ -127,19 +134,19 @@ get_scrap_from_symbol (sym, clear_p, scrap)
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
@@ -147,138 +154,154 @@ get_scrap_from_symbol (sym, clear_p, scrap)
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
152static ScrapFlavorType 160static ScrapFlavorType
153get_flavor_type_from_symbol (sym) 161get_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)));
170 else
171 flavor_type = 0;
172
173 if (flavor_type && sel)
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 }
160 190
161 return 0; 191 return flavor_type;
162} 192}
163 193
164/* Check if the symbol SYM has a corresponding scrap flavor type. */ 194/* Check if the symbol SYM has a corresponding selection target type. */
165 195
166static int 196static int
167valid_scrap_target_type_p (sym) 197mac_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
175static INLINE OSStatus 205static OSStatus
176clear_scrap (scrap) 206mac_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. */
192 228
193static OSStatus 229static Lisp_Object
194put_scrap_string (scrap, type, str) 230mac_get_selection_ownership_info (sel)
195 ScrapRef scrap; 231 Selection sel;
196 Lisp_Object type, str;
197{ 232{
198 ScrapFlavorType flavor_type = get_flavor_type_from_symbol (type);
199
200 if (flavor_type == 0)
201 return noTypeErr;
202
203#if TARGET_API_MAC_CARBON 233#if TARGET_API_MAC_CARBON
204 return PutScrapFlavor (scrap, flavor_type, kScrapFlavorMaskNone, 234 return long_to_cons ((unsigned long) sel);
205 SBYTES (str), SDATA (str));
206#else /* !TARGET_API_MAC_CARBON */ 235#else /* !TARGET_API_MAC_CARBON */
207 return PutScrap (SBYTES (str), flavor_type, SDATA (str)); 236 ScrapStuffPtr scrap_info = InfoScrap ();
237
238 return make_number (scrap_info->scrapCount);
208#endif /* !TARGET_API_MAC_CARBON */ 239#endif /* !TARGET_API_MAC_CARBON */
209} 240}
210 241
211/* Put TIMESTAMP to the scrap SCRAP. The timestamp is used for 242/* Return non-zero if VALUE is a valid selection value for TARGET. */
212 checking if the scrap is owned by the process. */
213 243
214static INLINE OSStatus 244static int
215put_scrap_private_timestamp (scrap, timestamp) 245mac_valid_selection_value_p (value, target)
216 ScrapRef scrap; 246 Lisp_Object value, target;
217 unsigned long timestamp;
218{ 247{
219#if TARGET_API_MAC_CARBON 248 return STRINGP (value);
220 return PutScrapFlavor (scrap, SCRAP_FLAVOR_TYPE_EMACS_TIMESTAMP,
221 kScrapFlavorMaskSenderOnly,
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} 249}
228 250
229/* Check if data for the target type TYPE is available in SCRAP. */ 251/* Put Lisp Object VALUE to the selection SEL. The target type is
252 specified by TARGET. */
230 253
231static ScrapFlavorType 254static OSStatus
232scrap_has_target_type (scrap, type) 255mac_put_selection_value (sel, target, value)
233 ScrapRef scrap; 256 Selection sel;
234 Lisp_Object type; 257 Lisp_Object target, value;
235{ 258{
236 OSStatus err; 259 ScrapFlavorType flavor_type = get_flavor_type_from_symbol (target, 0);
237 ScrapFlavorType flavor_type = get_flavor_type_from_symbol (type);
238 260
239 if (flavor_type) 261 if (flavor_type == 0 || !STRINGP (value))
240 { 262 return noTypeErr;
241#if TARGET_API_MAC_CARBON
242 ScrapFlavorFlags flags;
243 263
244 err = GetScrapFlavorFlags (scrap, flavor_type, &flags); 264#if TARGET_API_MAC_CARBON
245 if (err != noErr) 265 return PutScrapFlavor (sel, flavor_type, kScrapFlavorMaskNone,
246 flavor_type = 0; 266 SBYTES (value), SDATA (value));
247#else /* !TARGET_API_MAC_CARBON */ 267#else /* !TARGET_API_MAC_CARBON */
248 SInt32 size, offset; 268 return PutScrap (SBYTES (value), flavor_type, SDATA (value));
249
250 size = GetScrap (NULL, flavor_type, &offset);
251 if (size < 0)
252 flavor_type = 0;
253#endif /* !TARGET_API_MAC_CARBON */ 269#endif /* !TARGET_API_MAC_CARBON */
254 } 270}
255 271
256 return flavor_type; 272/* Check if data for the target type TARGET is available in SEL. */
273
274static int
275mac_selection_has_target_p (sel, target)
276 Selection sel;
277 Lisp_Object target;
278{
279 return get_flavor_type_from_symbol (target, sel) != 0;
257} 280}
258 281
259/* Get data for the target type TYPE from SCRAP and create a Lisp 282/* Get data for the target type TARGET from SEL and create a Lisp
260 string. Return nil if failed to get data. */ 283 string. Return nil if failed to get data. */
261 284
262static Lisp_Object 285static Lisp_Object
263get_scrap_string (scrap, type) 286mac_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;
@@ -308,72 +331,25 @@ get_scrap_string (scrap, type)
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
313static OSStatus
314get_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
362static Lisp_Object 338static Lisp_Object
363get_scrap_target_type_list (scrap) 339mac_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);
@@ -387,11 +363,11 @@ get_scrap_target_type_list (scrap)
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)
@@ -428,9 +404,9 @@ 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);
@@ -439,8 +415,8 @@ x_own_selection (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
@@ -451,49 +427,60 @@ x_own_selection (selection_name, selection_value)
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);
440
441 if (NILP (value))
442 continue;
464 443
465 if (STRINGP (value)) 444 if (mac_valid_selection_value_p (value, target_type))
466 err = put_scrap_string (scrap, type, value); 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);
@@ -574,29 +561,20 @@ x_get_local_selection (selection_symbol, target_type, local_request)
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",
@@ -676,22 +654,22 @@ 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);
@@ -770,7 +748,7 @@ Disowning it means there is no such 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 ();
@@ -812,9 +790,9 @@ Disowning it means there is no such selection. */)
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
@@ -833,7 +811,7 @@ and t is the same as `SECONDARY'. */)
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 ();
@@ -848,15 +826,14 @@ and t is the same as `SECONDARY'. */)
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
@@ -878,7 +855,7 @@ and t is the same as `SECONDARY'. */)
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. */
@@ -893,12 +870,12 @@ and t is the same as `SECONDARY'. */)
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;
@@ -1623,16 +1600,19 @@ remove_drag_handler (window)
1623 Services menu support 1600 Services menu support
1624***********************************************************************/ 1601***********************************************************************/
1625#ifdef MAC_OSX 1602#ifdef MAC_OSX
1626void 1603OSStatus
1627init_service_handler () 1604install_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
1638extern OSStatus mac_store_service_event P_ ((EventRef)); 1618extern OSStatus mac_store_service_event P_ ((EventRef));
@@ -1697,7 +1677,7 @@ mac_handle_service_event (call_ref, event, data)
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
@@ -1716,7 +1696,7 @@ mac_handle_service_event (call_ref, event, data)
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)
@@ -1801,14 +1781,15 @@ mac_handle_service_event (call_ref, event, data)
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,