diff options
Diffstat (limited to 'src/macselect.c')
| -rw-r--r-- | src/macselect.c | 404 |
1 files changed, 189 insertions, 215 deletions
diff --git a/src/macselect.c b/src/macselect.c index 04034c499b7..9515a5774ec 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 |
| 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, |
| @@ -56,7 +61,7 @@ void init_service_handler P_ ((void)); | |||
| 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. */ |
| @@ -70,23 +75,24 @@ static Lisp_Object Qforeign_selection; | |||
| 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 | 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; | |||
| 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 |
| @@ -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 | ||
| 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))); |
| 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; | ||
| 160 | 178 | ||
| 161 | return 0; | 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; | ||
| 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 | ||
| 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. */ | ||
| 192 | 228 | ||
| 193 | static OSStatus | 229 | static Lisp_Object |
| 194 | put_scrap_string (scrap, type, str) | 230 | mac_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 | ||
| 214 | static INLINE OSStatus | 244 | static int |
| 215 | put_scrap_private_timestamp (scrap, timestamp) | 245 | mac_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), ×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 | } | 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 | ||
| 231 | static ScrapFlavorType | 254 | static OSStatus |
| 232 | scrap_has_target_type (scrap, type) | 255 | mac_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 | |||
| 274 | static int | ||
| 275 | mac_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 | ||
| 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; |
| @@ -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 | |
| 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); |
| @@ -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,56 @@ 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 | ownership_info = mac_get_selection_ownership_info (sel); | ||
| 472 | else | ||
| 473 | ownership_info = Qnil; /* dummy value for local-only selection */ | ||
| 493 | selection_data = Fcons (selection_name, | 474 | selection_data = Fcons (selection_name, |
| 494 | Fcons (selection_value, | 475 | Fcons (selection_value, |
| 495 | Fcons (selection_time, | 476 | Fcons (selection_time, |
| 496 | Fcons (selected_frame, Qnil)))); | 477 | Fcons (selected_frame, |
| 478 | Fcons (ownership_info, | ||
| 479 | Qnil))))); | ||
| 497 | prev_value = assq_no_quit (selection_name, Vselection_alist); | 480 | prev_value = assq_no_quit (selection_name, Vselection_alist); |
| 498 | 481 | ||
| 499 | Vselection_alist = Fcons (selection_data, Vselection_alist); | 482 | Vselection_alist = Fcons (selection_data, Vselection_alist); |
| @@ -574,29 +557,20 @@ x_get_local_selection (selection_symbol, target_type, local_request) | |||
| 574 | unbind_to (count, Qnil); | 557 | unbind_to (count, Qnil); |
| 575 | } | 558 | } |
| 576 | 559 | ||
| 560 | if (local_request) | ||
| 561 | return value; | ||
| 562 | |||
| 577 | /* Make sure this value is of a type that we could transmit | 563 | /* Make sure this value is of a type that we could transmit |
| 578 | to another X client. */ | 564 | to another application. */ |
| 579 | 565 | ||
| 566 | type = target_type; | ||
| 580 | check = value; | 567 | check = value; |
| 581 | if (CONSP (value) | 568 | if (CONSP (value) |
| 582 | && SYMBOLP (XCAR (value))) | 569 | && SYMBOLP (XCAR (value))) |
| 583 | type = XCAR (value), | 570 | type = XCAR (value), |
| 584 | check = XCDR (value); | 571 | check = XCDR (value); |
| 585 | 572 | ||
| 586 | if (STRINGP (check) | 573 | 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; | 574 | return value; |
| 601 | 575 | ||
| 602 | signal_error ("Invalid data returned by selection-conversion function", | 576 | signal_error ("Invalid data returned by selection-conversion function", |
| @@ -676,22 +650,22 @@ x_get_foreign_selection (selection_symbol, target_type, time_stamp) | |||
| 676 | Lisp_Object selection_symbol, target_type, time_stamp; | 650 | Lisp_Object selection_symbol, target_type, time_stamp; |
| 677 | { | 651 | { |
| 678 | OSStatus err; | 652 | OSStatus err; |
| 679 | ScrapRef scrap; | 653 | Selection sel; |
| 680 | Lisp_Object result = Qnil; | 654 | Lisp_Object result = Qnil; |
| 681 | 655 | ||
| 682 | BLOCK_INPUT; | 656 | BLOCK_INPUT; |
| 683 | 657 | ||
| 684 | err = get_scrap_from_symbol (selection_symbol, 0, &scrap); | 658 | err = mac_get_selection_from_symbol (selection_symbol, 0, &sel); |
| 685 | if (err == noErr && scrap) | 659 | if (err == noErr && sel) |
| 686 | { | 660 | { |
| 687 | if (EQ (target_type, QTARGETS)) | 661 | if (EQ (target_type, QTARGETS)) |
| 688 | { | 662 | { |
| 689 | result = get_scrap_target_type_list (scrap); | 663 | result = mac_get_selection_target_list (sel); |
| 690 | result = Fvconcat (1, &result); | 664 | result = Fvconcat (1, &result); |
| 691 | } | 665 | } |
| 692 | else | 666 | else |
| 693 | { | 667 | { |
| 694 | result = get_scrap_string (scrap, target_type); | 668 | result = mac_get_selection_value (sel, target_type); |
| 695 | if (STRINGP (result)) | 669 | if (STRINGP (result)) |
| 696 | Fput_text_property (make_number (0), make_number (SBYTES (result)), | 670 | Fput_text_property (make_number (0), make_number (SBYTES (result)), |
| 697 | Qforeign_selection, target_type, result); | 671 | Qforeign_selection, target_type, result); |
| @@ -770,7 +744,7 @@ Disowning it means there is no such selection. */) | |||
| 770 | Lisp_Object time; | 744 | Lisp_Object time; |
| 771 | { | 745 | { |
| 772 | OSStatus err; | 746 | OSStatus err; |
| 773 | ScrapRef scrap; | 747 | Selection sel; |
| 774 | Lisp_Object local_selection_data; | 748 | Lisp_Object local_selection_data; |
| 775 | 749 | ||
| 776 | check_mac (); | 750 | check_mac (); |
| @@ -812,9 +786,9 @@ Disowning it means there is no such selection. */) | |||
| 812 | 786 | ||
| 813 | BLOCK_INPUT; | 787 | BLOCK_INPUT; |
| 814 | 788 | ||
| 815 | err = get_scrap_from_symbol (selection, 0, &scrap); | 789 | err = mac_get_selection_from_symbol (selection, 0, &sel); |
| 816 | if (err == noErr && scrap) | 790 | if (err == noErr && sel) |
| 817 | clear_scrap (&scrap); | 791 | mac_clear_selection (&sel); |
| 818 | 792 | ||
| 819 | UNBLOCK_INPUT; | 793 | UNBLOCK_INPUT; |
| 820 | 794 | ||
| @@ -833,7 +807,7 @@ and t is the same as `SECONDARY'. */) | |||
| 833 | Lisp_Object selection; | 807 | Lisp_Object selection; |
| 834 | { | 808 | { |
| 835 | OSStatus err; | 809 | OSStatus err; |
| 836 | ScrapRef scrap; | 810 | Selection sel; |
| 837 | Lisp_Object result = Qnil, local_selection_data; | 811 | Lisp_Object result = Qnil, local_selection_data; |
| 838 | 812 | ||
| 839 | check_mac (); | 813 | check_mac (); |
| @@ -848,15 +822,14 @@ and t is the same as `SECONDARY'. */) | |||
| 848 | 822 | ||
| 849 | BLOCK_INPUT; | 823 | BLOCK_INPUT; |
| 850 | 824 | ||
| 851 | err = get_scrap_from_symbol (selection, 0, &scrap); | 825 | err = mac_get_selection_from_symbol (selection, 0, &sel); |
| 852 | if (err == noErr && scrap) | 826 | if (err == noErr && sel) |
| 853 | { | 827 | { |
| 854 | unsigned long timestamp; | 828 | Lisp_Object ownership_info; |
| 855 | 829 | ||
| 856 | err = get_scrap_private_timestamp (scrap, ×tamp); | 830 | ownership_info = XCAR (XCDR (XCDR (XCDR (XCDR (local_selection_data))))); |
| 857 | if (err == noErr | 831 | if (!NILP (Fequal (ownership_info, |
| 858 | && (timestamp | 832 | mac_get_selection_ownership_info (sel)))) |
| 859 | == cons_to_long (XCAR (XCDR (XCDR (local_selection_data)))))) | ||
| 860 | result = Qt; | 833 | result = Qt; |
| 861 | } | 834 | } |
| 862 | else | 835 | else |
| @@ -878,7 +851,7 @@ and t is the same as `SECONDARY'. */) | |||
| 878 | Lisp_Object selection; | 851 | Lisp_Object selection; |
| 879 | { | 852 | { |
| 880 | OSStatus err; | 853 | OSStatus err; |
| 881 | ScrapRef scrap; | 854 | Selection sel; |
| 882 | Lisp_Object result = Qnil, rest; | 855 | Lisp_Object result = Qnil, rest; |
| 883 | 856 | ||
| 884 | /* It should be safe to call this before we have an Mac frame. */ | 857 | /* It should be safe to call this before we have an Mac frame. */ |
| @@ -893,12 +866,12 @@ and t is the same as `SECONDARY'. */) | |||
| 893 | 866 | ||
| 894 | BLOCK_INPUT; | 867 | BLOCK_INPUT; |
| 895 | 868 | ||
| 896 | err = get_scrap_from_symbol (selection, 0, &scrap); | 869 | err = mac_get_selection_from_symbol (selection, 0, &sel); |
| 897 | if (err == noErr && scrap) | 870 | if (err == noErr && sel) |
| 898 | for (rest = Vselection_converter_alist; CONSP (rest); rest = XCDR (rest)) | 871 | for (rest = Vselection_converter_alist; CONSP (rest); rest = XCDR (rest)) |
| 899 | { | 872 | { |
| 900 | if (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest))) | 873 | if (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest))) |
| 901 | && scrap_has_target_type (scrap, XCAR (XCAR (rest)))) | 874 | && mac_selection_has_target_p (sel, XCAR (XCAR (rest)))) |
| 902 | { | 875 | { |
| 903 | result = Qt; | 876 | result = Qt; |
| 904 | break; | 877 | break; |
| @@ -1700,7 +1673,7 @@ mac_handle_service_event (call_ref, event, data) | |||
| 1700 | if (!SYMBOLP (Vmac_service_selection)) | 1673 | if (!SYMBOLP (Vmac_service_selection)) |
| 1701 | err = eventNotHandledErr; | 1674 | err = eventNotHandledErr; |
| 1702 | else | 1675 | else |
| 1703 | err = get_scrap_from_symbol (Vmac_service_selection, 0, &cur_scrap); | 1676 | err = mac_get_selection_from_symbol (Vmac_service_selection, 0, &cur_scrap); |
| 1704 | if (!(err == noErr && cur_scrap)) | 1677 | if (!(err == noErr && cur_scrap)) |
| 1705 | return eventNotHandledErr; | 1678 | return eventNotHandledErr; |
| 1706 | 1679 | ||
| @@ -1719,7 +1692,7 @@ mac_handle_service_event (call_ref, event, data) | |||
| 1719 | rest = XCDR (rest)) | 1692 | rest = XCDR (rest)) |
| 1720 | if (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest))) | 1693 | if (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest))) |
| 1721 | && (flavor_type = | 1694 | && (flavor_type = |
| 1722 | get_flavor_type_from_symbol (XCAR (XCAR (rest))))) | 1695 | get_flavor_type_from_symbol (XCAR (XCAR (rest)), 0))) |
| 1723 | { | 1696 | { |
| 1724 | type = CreateTypeStringWithOSType (flavor_type); | 1697 | type = CreateTypeStringWithOSType (flavor_type); |
| 1725 | if (type) | 1698 | if (type) |
| @@ -1804,14 +1777,15 @@ mac_handle_service_event (call_ref, event, data) | |||
| 1804 | NULL, sizeof (ScrapRef), NULL, | 1777 | NULL, sizeof (ScrapRef), NULL, |
| 1805 | &specific_scrap); | 1778 | &specific_scrap); |
| 1806 | if (err == noErr) | 1779 | if (err == noErr) |
| 1807 | err = clear_scrap (&cur_scrap); | 1780 | err = mac_clear_selection (&cur_scrap); |
| 1808 | if (err == noErr) | 1781 | if (err == noErr) |
| 1809 | for (rest = Vselection_converter_alist; CONSP (rest); | 1782 | for (rest = Vselection_converter_alist; CONSP (rest); |
| 1810 | rest = XCDR (rest)) | 1783 | rest = XCDR (rest)) |
| 1811 | { | 1784 | { |
| 1812 | if (! (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest))))) | 1785 | if (! (CONSP (XCAR (rest)) && SYMBOLP (XCAR (XCAR (rest))))) |
| 1813 | continue; | 1786 | continue; |
| 1814 | flavor_type = get_flavor_type_from_symbol (XCAR (XCAR (rest))); | 1787 | flavor_type = get_flavor_type_from_symbol (XCAR (XCAR (rest)), |
| 1788 | specific_scrap); | ||
| 1815 | if (flavor_type == 0) | 1789 | if (flavor_type == 0) |
| 1816 | continue; | 1790 | continue; |
| 1817 | err = copy_scrap_flavor_data (specific_scrap, cur_scrap, | 1791 | err = copy_scrap_flavor_data (specific_scrap, cur_scrap, |