aboutsummaryrefslogtreecommitdiffstats
path: root/src/nsselect.m
diff options
context:
space:
mode:
Diffstat (limited to 'src/nsselect.m')
-rw-r--r--src/nsselect.m276
1 files changed, 129 insertions, 147 deletions
diff --git a/src/nsselect.m b/src/nsselect.m
index 867cf3252e5..4d901fac2ec 100644
--- a/src/nsselect.m
+++ b/src/nsselect.m
@@ -1,5 +1,5 @@
1/* NeXT/Open/GNUstep / MacOSX Cocoa selection processing for emacs. 1/* NeXT/Open/GNUstep / MacOSX Cocoa selection processing for emacs.
2 Copyright (C) 1993-1994, 2005-2006, 2008-2011 2 Copyright (C) 1993-1994, 2005-2006, 2008-2012
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 4
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
@@ -35,8 +35,6 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu)
35#include "termhooks.h" 35#include "termhooks.h"
36#include "keyboard.h" 36#include "keyboard.h"
37 37
38#define CUT_BUFFER_SUPPORT
39
40Lisp_Object QCLIPBOARD, QSECONDARY, QTEXT, QFILE_NAME; 38Lisp_Object QCLIPBOARD, QSECONDARY, QTEXT, QFILE_NAME;
41 39
42static Lisp_Object Vselection_alist; 40static Lisp_Object Vselection_alist;
@@ -60,13 +58,18 @@ static NSString *
60symbol_to_nsstring (Lisp_Object sym) 58symbol_to_nsstring (Lisp_Object sym)
61{ 59{
62 CHECK_SYMBOL (sym); 60 CHECK_SYMBOL (sym);
63 if (EQ (sym, QCLIPBOARD)) return NSGeneralPboard; 61 if (EQ (sym, QCLIPBOARD)) return NSGeneralPboard;
64 if (EQ (sym, QPRIMARY)) return NXPrimaryPboard; 62 if (EQ (sym, QPRIMARY)) return NXPrimaryPboard;
65 if (EQ (sym, QSECONDARY)) return NXSecondaryPboard; 63 if (EQ (sym, QSECONDARY)) return NXSecondaryPboard;
66 if (EQ (sym, QTEXT)) return NSStringPboardType; 64 if (EQ (sym, QTEXT)) return NSStringPboardType;
67 return [NSString stringWithUTF8String: SDATA (XSYMBOL (sym)->xname)]; 65 return [NSString stringWithUTF8String: SDATA (XSYMBOL (sym)->xname)];
68} 66}
69 67
68static NSPasteboard *
69ns_symbol_to_pb (Lisp_Object symbol)
70{
71 return [NSPasteboard pasteboardWithName: symbol_to_nsstring (symbol)];
72}
70 73
71static Lisp_Object 74static Lisp_Object
72ns_string_to_symbol (NSString *t) 75ns_string_to_symbol (NSString *t)
@@ -230,70 +233,11 @@ static Lisp_Object
230ns_get_foreign_selection (Lisp_Object symbol, Lisp_Object target) 233ns_get_foreign_selection (Lisp_Object symbol, Lisp_Object target)
231{ 234{
232 id pb; 235 id pb;
233 pb =[NSPasteboard pasteboardWithName: symbol_to_nsstring (symbol)]; 236 pb = ns_symbol_to_pb (symbol);
234 return ns_string_from_pasteboard (pb); 237 return pb != nil ? ns_string_from_pasteboard (pb) : Qnil;
235}
236
237
238static void
239ns_handle_selection_request (struct input_event *event)
240{
241 // FIXME: BIG UGLY HACK!!!
242 id pb = (id)*(EMACS_INT*)&(event->x);
243 NSString *type = (NSString *)*(EMACS_INT*)&(event->y);
244 Lisp_Object selection_name, selection_data, target_symbol, data;
245 Lisp_Object successful_p, rest;
246
247 selection_name = ns_string_to_symbol ([(NSPasteboard *)pb name]);
248 target_symbol = ns_string_to_symbol (type);
249 selection_data = assq_no_quit (selection_name, Vselection_alist);
250 successful_p = Qnil;
251
252 if (!NILP (selection_data))
253 {
254 data = ns_get_local_selection (selection_name, target_symbol);
255 if (!NILP (data))
256 {
257 if (STRINGP (data))
258 ns_string_to_pasteboard_internal (pb, data, type);
259 successful_p = Qt;
260 }
261 }
262
263 if (!EQ (Vns_sent_selection_hooks, Qunbound))
264 {
265 for (rest = Vns_sent_selection_hooks; CONSP (rest); rest = Fcdr (rest))
266 call3 (Fcar (rest), selection_name, target_symbol, successful_p);
267 }
268} 238}
269 239
270 240
271static void
272ns_handle_selection_clear (struct input_event *event)
273{
274 id pb = (id)*(EMACS_INT*)&(event->x);
275 Lisp_Object selection_name, selection_data, rest;
276
277 selection_name = ns_string_to_symbol ([(NSPasteboard *)pb name]);
278 selection_data = assq_no_quit (selection_name, Vselection_alist);
279 if (NILP (selection_data)) return;
280
281 if (EQ (selection_data, Fcar (Vselection_alist)))
282 Vselection_alist = Fcdr (Vselection_alist);
283 else
284 {
285 for (rest = Vselection_alist; !NILP (rest); rest = Fcdr (rest))
286 if (EQ (selection_data, Fcar (Fcdr (rest))))
287 Fsetcdr (rest, Fcdr (Fcdr (rest)));
288 }
289
290 if (!EQ (Vns_lost_selection_hooks, Qunbound))
291 {
292 for (rest = Vns_lost_selection_hooks;CONSP (rest); rest = Fcdr (rest))
293 call1 (Fcar (rest), selection_name);
294 }
295}
296
297 241
298 242
299/* ========================================================================== 243/* ==========================================================================
@@ -392,66 +336,103 @@ ns_string_to_pasteboard (id pb, Lisp_Object str)
392 336
393 337
394DEFUN ("x-own-selection-internal", Fx_own_selection_internal, 338DEFUN ("x-own-selection-internal", Fx_own_selection_internal,
395 Sx_own_selection_internal, 2, 2, 0, 339 Sx_own_selection_internal, 2, 3, 0,
396 doc: /* Assert a selection. 340 doc: /* Assert an X selection of type SELECTION and value VALUE.
397SELECTION-NAME is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. 341SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
342\(Those are literal upper-case symbol names, since that's what X expects.)
398VALUE is typically a string, or a cons of two markers, but may be 343VALUE is typically a string, or a cons of two markers, but may be
399anything that the functions on `selection-converter-alist' know about. */) 344anything that the functions on `selection-converter-alist' know about.
400 (Lisp_Object selection_name, Lisp_Object selection_value) 345
346FRAME should be a frame that should own the selection. If omitted or
347nil, it defaults to the selected frame.
348
349On Nextstep, FRAME is unused. */)
350 (Lisp_Object selection, Lisp_Object value, Lisp_Object frame)
401{ 351{
402 id pb; 352 id pb;
403 Lisp_Object old_value, new_value; 353 Lisp_Object old_value, new_value;
354 NSString *type;
355 Lisp_Object successful_p = Qnil, rest;
356 Lisp_Object target_symbol, data;
357
404 358
405 check_ns (); 359 check_ns ();
406 CHECK_SYMBOL (selection_name); 360 CHECK_SYMBOL (selection);
407 if (NILP (selection_value)) 361 if (NILP (value))
408 error ("selection-value may not be nil."); 362 error ("selection value may not be nil.");
409 pb =[NSPasteboard pasteboardWithName: symbol_to_nsstring (selection_name)]; 363 pb = ns_symbol_to_pb (selection);
364 if (pb == nil) return Qnil;
365
410 ns_declare_pasteboard (pb); 366 ns_declare_pasteboard (pb);
411 old_value = assq_no_quit (selection_name, Vselection_alist); 367 old_value = assq_no_quit (selection, Vselection_alist);
412 new_value = Fcons (selection_name, Fcons (selection_value, Qnil)); 368 new_value = Fcons (selection, Fcons (value, Qnil));
369
413 if (NILP (old_value)) 370 if (NILP (old_value))
414 Vselection_alist = Fcons (new_value, Vselection_alist); 371 Vselection_alist = Fcons (new_value, Vselection_alist);
415 else 372 else
416 Fsetcdr (old_value, Fcdr (new_value)); 373 Fsetcdr (old_value, Fcdr (new_value));
417 /* XXX An evil hack, but a necessary one I fear XXX */ 374
418 { 375 /* We only support copy of text. */
419 struct input_event ev; 376 type = NSStringPboardType;
420 ev.kind = SELECTION_REQUEST_EVENT; 377 target_symbol = ns_string_to_symbol (type);
421 ev.modifiers = 0; 378 data = ns_get_local_selection (selection, target_symbol);
422 ev.code = 0; 379 if (!NILP (data))
423 *(EMACS_INT*)(&(ev.x)) = (EMACS_INT)pb; // FIXME: BIG UGLY HACK!! 380 {
424 *(EMACS_INT*)(&(ev.y)) = (EMACS_INT)NSStringPboardType; 381 if (STRINGP (data))
425 ns_handle_selection_request (&ev); 382 ns_string_to_pasteboard_internal (pb, data, type);
426 } 383 successful_p = Qt;
427 return selection_value; 384 }
385
386 if (!EQ (Vns_sent_selection_hooks, Qunbound))
387 {
388 for (rest = Vns_sent_selection_hooks; CONSP (rest); rest = Fcdr (rest))
389 call3 (Fcar (rest), selection, target_symbol, successful_p);
390 }
391
392 return value;
428} 393}
429 394
430 395
431DEFUN ("x-disown-selection-internal", Fx_disown_selection_internal, 396DEFUN ("x-disown-selection-internal", Fx_disown_selection_internal,
432 Sx_disown_selection_internal, 1, 2, 0, 397 Sx_disown_selection_internal, 1, 3, 0,
433 doc: /* If we own the selection SELECTION, disown it. */) 398 doc: /* If we own the selection SELECTION, disown it.
434 (Lisp_Object selection_name, Lisp_Object time) 399Disowning it means there is no such selection.
400
401Sets the last-change time for the selection to TIME-OBJECT (by default
402the time of the last event).
403
404TERMINAL should be a terminal object or a frame specifying the X
405server to query. If omitted or nil, that stands for the selected
406frame's display, or the first available X display.
407
408On Nextstep, the TIME-OBJECT and TERMINAL arguments are unused.
409On MS-DOS, all this does is return non-nil if we own the selection. */)
410 (Lisp_Object selection, Lisp_Object time_object, Lisp_Object terminal)
435{ 411{
436 id pb; 412 id pb;
437 check_ns (); 413 check_ns ();
438 CHECK_SYMBOL (selection_name); 414 CHECK_SYMBOL (selection);
439 if (NILP (assq_no_quit (selection_name, Vselection_alist))) return Qnil; 415 if (NILP (assq_no_quit (selection, Vselection_alist))) return Qnil;
440 416
441 pb =[NSPasteboard pasteboardWithName: symbol_to_nsstring (selection_name)]; 417 pb = ns_symbol_to_pb (selection);
442 ns_undeclare_pasteboard (pb); 418 if (pb != nil) ns_undeclare_pasteboard (pb);
443 return Qt; 419 return Qt;
444} 420}
445 421
446 422
447DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p, 423DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
448 0, 1, 0, doc: /* Whether there is an owner for the given selection. 424 0, 2, 0, doc: /* Whether there is an owner for the given X selection.
449The arg should be the name of the selection in question, typically one of 425SELECTION should be the name of the selection in question, typically
450the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'. 426one of the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'. (X expects
451\(Those are literal upper-case symbol names.) 427these literal upper-case names.) The symbol nil is the same as
452For convenience, the symbol nil is the same as `PRIMARY', 428`PRIMARY', and t is the same as `SECONDARY'.
453and t is the same as `SECONDARY'.) */) 429
454 (Lisp_Object selection) 430TERMINAL should be a terminal object or a frame specifying the X
431server to query. If omitted or nil, that stands for the selected
432frame's display, or the first available X display.
433
434On Nextstep, TERMINAL is unused. */)
435 (Lisp_Object selection, Lisp_Object terminal)
455{ 436{
456 id pb; 437 id pb;
457 NSArray *types; 438 NSArray *types;
@@ -460,21 +441,29 @@ and t is the same as `SECONDARY'.) */)
460 CHECK_SYMBOL (selection); 441 CHECK_SYMBOL (selection);
461 if (EQ (selection, Qnil)) selection = QPRIMARY; 442 if (EQ (selection, Qnil)) selection = QPRIMARY;
462 if (EQ (selection, Qt)) selection = QSECONDARY; 443 if (EQ (selection, Qt)) selection = QSECONDARY;
463 pb =[NSPasteboard pasteboardWithName: symbol_to_nsstring (selection)]; 444 pb = ns_symbol_to_pb (selection);
464 types =[pb types]; 445 if (pb == nil) return Qnil;
446
447 types = [pb types];
465 return ([types count] == 0) ? Qnil : Qt; 448 return ([types count] == 0) ? Qnil : Qt;
466} 449}
467 450
468 451
469DEFUN ("x-selection-owner-p", Fx_selection_owner_p, Sx_selection_owner_p, 452DEFUN ("x-selection-owner-p", Fx_selection_owner_p, Sx_selection_owner_p,
470 0, 1, 0, 453 0, 2, 0,
471 doc: /* Whether the current Emacs process owns the given selection. 454 doc: /* Whether the current Emacs process owns the given X Selection.
472The arg should be the name of the selection in question, typically one of 455The arg should be the name of the selection in question, typically one of
473the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'. 456the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
474\(Those are literal upper-case symbol names.) 457\(Those are literal upper-case symbol names, since that's what X expects.)
475For convenience, the symbol nil is the same as `PRIMARY', 458For convenience, the symbol nil is the same as `PRIMARY',
476and t is the same as `SECONDARY'.) */) 459and t is the same as `SECONDARY'.
477 (Lisp_Object selection) 460
461TERMINAL should be a terminal object or a frame specifying the X
462server to query. If omitted or nil, that stands for the selected
463frame's display, or the first available X display.
464
465On Nextstep, TERMINAL is unused. */)
466 (Lisp_Object selection, Lisp_Object terminal)
478{ 467{
479 check_ns (); 468 check_ns ();
480 CHECK_SYMBOL (selection); 469 CHECK_SYMBOL (selection);
@@ -485,12 +474,22 @@ and t is the same as `SECONDARY'.) */)
485 474
486 475
487DEFUN ("x-get-selection-internal", Fx_get_selection_internal, 476DEFUN ("x-get-selection-internal", Fx_get_selection_internal,
488 Sx_get_selection_internal, 2, 2, 0, 477 Sx_get_selection_internal, 2, 4, 0,
489 doc: /* Return text selected from some pasteboard. 478 doc: /* Return text selected from some X window.
490SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. 479SELECTION-SYMBOL is typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
491\(Those are literal upper-case symbol names.) 480\(Those are literal upper-case symbol names, since that's what X expects.)
492TYPE is the type of data desired, typically `STRING'. */) 481TARGET-TYPE is the type of data desired, typically `STRING'.
493 (Lisp_Object selection_name, Lisp_Object target_type) 482
483TIME-STAMP is the time to use in the XConvertSelection call for foreign
484selections. If omitted, defaults to the time for the last event.
485
486TERMINAL should be a terminal object or a frame specifying the X
487server to query. If omitted or nil, that stands for the selected
488frame's display, or the first available X display.
489
490On Nextstep, TIME-STAMP and TERMINAL are unused. */)
491 (Lisp_Object selection_name, Lisp_Object target_type,
492 Lisp_Object time_stamp, Lisp_Object terminal)
494{ 493{
495 Lisp_Object val; 494 Lisp_Object val;
496 495
@@ -511,45 +510,31 @@ TYPE is the type of data desired, typically `STRING'. */)
511} 510}
512 511
513 512
514#ifdef CUT_BUFFER_SUPPORT 513DEFUN ("ns-get-selection-internal", Fns_get_selection_internal,
515DEFUN ("ns-get-cut-buffer-internal", Fns_get_cut_buffer_internal, 514 Sns_get_selection_internal, 1, 1, 0,
516 Sns_get_cut_buffer_internal, 1, 1, 0, 515 doc: /* Returns the value of SELECTION as a string.
517 doc: /* Returns the value of the named cut buffer. */) 516SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. */)
518 (Lisp_Object buffer) 517 (Lisp_Object selection)
519{ 518{
520 id pb; 519 id pb;
521 check_ns (); 520 check_ns ();
522 pb =[NSPasteboard pasteboardWithName: symbol_to_nsstring (buffer)]; 521 pb = ns_symbol_to_pb (selection);
523 return ns_string_from_pasteboard (pb); 522 return pb != nil ? ns_string_from_pasteboard (pb) : Qnil;
524} 523}
525 524
526 525
527DEFUN ("ns-rotate-cut-buffers-internal", Fns_rotate_cut_buffers_internal, 526DEFUN ("ns-store-selection-internal", Fns_store_selection_internal,
528 Sns_rotate_cut_buffers_internal, 1, 1, 0, 527 Sns_store_selection_internal, 2, 2, 0,
529 doc: /* Rotate the values of the cut buffers by N steps. 528 doc: /* Sets the string value of SELECTION.
530Positive N means move values forward, negative means 529SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. */)
531backward. CURRENTLY NOT IMPLEMENTED UNDER NEXTSTEP. */ ) 530 (Lisp_Object selection, Lisp_Object string)
532 (Lisp_Object n)
533{
534 /* XXX This function is unimplemented under NeXTstep XXX */
535 Fsignal (Qquit, Fcons (build_string (
536 "Warning: ns-rotate-cut-buffers-internal not implemented\n"), Qnil));
537 return Qnil;
538}
539
540
541DEFUN ("ns-store-cut-buffer-internal", Fns_store_cut_buffer_internal,
542 Sns_store_cut_buffer_internal, 2, 2, 0,
543 doc: /* Sets the value of the named cut buffer (typically CUT_BUFFER0). */)
544 (Lisp_Object buffer, Lisp_Object string)
545{ 531{
546 id pb; 532 id pb;
547 check_ns (); 533 check_ns ();
548 pb =[NSPasteboard pasteboardWithName: symbol_to_nsstring (buffer)]; 534 pb = ns_symbol_to_pb (selection);
549 ns_string_to_pasteboard (pb, string); 535 if (pb != nil) ns_string_to_pasteboard (pb, string);
550 return Qnil; 536 return Qnil;
551} 537}
552#endif
553 538
554 539
555void 540void
@@ -572,11 +557,8 @@ syms_of_nsselect (void)
572 defsubr (&Sx_own_selection_internal); 557 defsubr (&Sx_own_selection_internal);
573 defsubr (&Sx_selection_exists_p); 558 defsubr (&Sx_selection_exists_p);
574 defsubr (&Sx_selection_owner_p); 559 defsubr (&Sx_selection_owner_p);
575#ifdef CUT_BUFFER_SUPPORT 560 defsubr (&Sns_get_selection_internal);
576 defsubr (&Sns_get_cut_buffer_internal); 561 defsubr (&Sns_store_selection_internal);
577 defsubr (&Sns_rotate_cut_buffers_internal);
578 defsubr (&Sns_store_cut_buffer_internal);
579#endif
580 562
581 Vselection_alist = Qnil; 563 Vselection_alist = Qnil;
582 staticpro (&Vselection_alist); 564 staticpro (&Vselection_alist);