/* NeXT/Open/GNUstep / MacOSX Cocoa selection processing for emacs.
- Copyright (C) 1993-1994, 2005-2006, 2008-2011
+ Copyright (C) 1993-1994, 2005-2006, 2008-2012
Free Software Foundation, Inc.
This file is part of GNU Emacs.
/* This should be the first include, as it may set up #defines affecting
interpretation of even the system includes. */
#include <config.h>
-#include <setjmp.h>
#include "lisp.h"
#include "nsterm.h"
#include "termhooks.h"
#include "keyboard.h"
-#define CUT_BUFFER_SUPPORT
-
Lisp_Object QCLIPBOARD, QSECONDARY, QTEXT, QFILE_NAME;
static Lisp_Object Vselection_alist;
symbol_to_nsstring (Lisp_Object sym)
{
CHECK_SYMBOL (sym);
- if (EQ (sym, QCLIPBOARD)) return NSGeneralPboard;
+ if (EQ (sym, QCLIPBOARD)) return NSGeneralPboard;
if (EQ (sym, QPRIMARY)) return NXPrimaryPboard;
if (EQ (sym, QSECONDARY)) return NXSecondaryPboard;
if (EQ (sym, QTEXT)) return NSStringPboardType;
- return [NSString stringWithUTF8String: SDATA (XSYMBOL (sym)->xname)];
+ return [NSString stringWithUTF8String: SSDATA (SYMBOL_NAME (sym))];
}
+static NSPasteboard *
+ns_symbol_to_pb (Lisp_Object symbol)
+{
+ return [NSPasteboard pasteboardWithName: symbol_to_nsstring (symbol)];
+}
static Lisp_Object
ns_string_to_symbol (NSString *t)
CHECK_STRING (str);
- utfStr = SDATA (str);
+ utfStr = SSDATA (str);
nsStr = [[NSString alloc] initWithBytesNoCopy: utfStr
length: SBYTES (str)
encoding: NSUTF8StringEncoding
ns_get_foreign_selection (Lisp_Object symbol, Lisp_Object target)
{
id pb;
- pb =[NSPasteboard pasteboardWithName: symbol_to_nsstring (symbol)];
- return ns_string_from_pasteboard (pb);
+ pb = ns_symbol_to_pb (symbol);
+ return pb != nil ? ns_string_from_pasteboard (pb) : Qnil;
}
-static void
-ns_handle_selection_request (struct input_event *event)
-{
- // FIXME: BIG UGLY HACK!!!
- id pb = (id)*(EMACS_INT*)&(event->x);
- NSString *type = (NSString *)*(EMACS_INT*)&(event->y);
- Lisp_Object selection_name, selection_data, target_symbol, data;
- Lisp_Object successful_p, rest;
-
- selection_name = ns_string_to_symbol ([(NSPasteboard *)pb name]);
- target_symbol = ns_string_to_symbol (type);
- selection_data = assq_no_quit (selection_name, Vselection_alist);
- successful_p = Qnil;
-
- if (!NILP (selection_data))
- {
- data = ns_get_local_selection (selection_name, target_symbol);
- if (!NILP (data))
- {
- if (STRINGP (data))
- ns_string_to_pasteboard_internal (pb, data, type);
- successful_p = Qt;
- }
- }
-
- if (!EQ (Vns_sent_selection_hooks, Qunbound))
- {
- for (rest = Vns_sent_selection_hooks; CONSP (rest); rest = Fcdr (rest))
- call3 (Fcar (rest), selection_name, target_symbol, successful_p);
- }
-}
-
-
-static void
-ns_handle_selection_clear (struct input_event *event)
-{
- id pb = (id)*(EMACS_INT*)&(event->x);
- Lisp_Object selection_name, selection_data, rest;
-
- selection_name = ns_string_to_symbol ([(NSPasteboard *)pb name]);
- selection_data = assq_no_quit (selection_name, Vselection_alist);
- if (NILP (selection_data)) return;
-
- if (EQ (selection_data, Fcar (Vselection_alist)))
- Vselection_alist = Fcdr (Vselection_alist);
- else
- {
- for (rest = Vselection_alist; !NILP (rest); rest = Fcdr (rest))
- if (EQ (selection_data, Fcar (Fcdr (rest))))
- Fsetcdr (rest, Fcdr (Fcdr (rest)));
- }
-
- if (!EQ (Vns_lost_selection_hooks, Qunbound))
- {
- for (rest = Vns_lost_selection_hooks;CONSP (rest); rest = Fcdr (rest))
- call1 (Fcar (rest), selection_name);
- }
-}
-
/* ==========================================================================
DEFUN ("x-own-selection-internal", Fx_own_selection_internal,
- Sx_own_selection_internal, 2, 2, 0,
- doc: /* Assert a selection.
-SELECTION-NAME is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
+ Sx_own_selection_internal, 2, 3, 0,
+ doc: /* Assert an X selection of type SELECTION and value VALUE.
+SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
+\(Those are literal upper-case symbol names, since that's what X expects.)
VALUE is typically a string, or a cons of two markers, but may be
-anything that the functions on `selection-converter-alist' know about. */)
- (Lisp_Object selection_name, Lisp_Object selection_value)
+anything that the functions on `selection-converter-alist' know about.
+
+FRAME should be a frame that should own the selection. If omitted or
+nil, it defaults to the selected frame.
+
+On Nextstep, FRAME is unused. */)
+ (Lisp_Object selection, Lisp_Object value, Lisp_Object frame)
{
id pb;
Lisp_Object old_value, new_value;
+ NSString *type;
+ Lisp_Object successful_p = Qnil, rest;
+ Lisp_Object target_symbol, data;
+
check_ns ();
- CHECK_SYMBOL (selection_name);
- if (NILP (selection_value))
- error ("selection-value may not be nil.");
- pb =[NSPasteboard pasteboardWithName: symbol_to_nsstring (selection_name)];
+ CHECK_SYMBOL (selection);
+ if (NILP (value))
+ error ("selection value may not be nil.");
+ pb = ns_symbol_to_pb (selection);
+ if (pb == nil) return Qnil;
+
ns_declare_pasteboard (pb);
- old_value = assq_no_quit (selection_name, Vselection_alist);
- new_value = Fcons (selection_name, Fcons (selection_value, Qnil));
+ old_value = assq_no_quit (selection, Vselection_alist);
+ new_value = Fcons (selection, Fcons (value, Qnil));
+
if (NILP (old_value))
Vselection_alist = Fcons (new_value, Vselection_alist);
else
Fsetcdr (old_value, Fcdr (new_value));
- /* XXX An evil hack, but a necessary one I fear XXX */
- {
- struct input_event ev;
- ev.kind = SELECTION_REQUEST_EVENT;
- ev.modifiers = 0;
- ev.code = 0;
- *(EMACS_INT*)(&(ev.x)) = (EMACS_INT)pb; // FIXME: BIG UGLY HACK!!
- *(EMACS_INT*)(&(ev.y)) = (EMACS_INT)NSStringPboardType;
- ns_handle_selection_request (&ev);
- }
- return selection_value;
+
+ /* We only support copy of text. */
+ type = NSStringPboardType;
+ target_symbol = ns_string_to_symbol (type);
+ data = ns_get_local_selection (selection, target_symbol);
+ if (!NILP (data))
+ {
+ if (STRINGP (data))
+ ns_string_to_pasteboard_internal (pb, data, type);
+ successful_p = Qt;
+ }
+
+ if (!EQ (Vns_sent_selection_hooks, Qunbound))
+ {
+ for (rest = Vns_sent_selection_hooks; CONSP (rest); rest = Fcdr (rest))
+ call3 (Fcar (rest), selection, target_symbol, successful_p);
+ }
+
+ return value;
}
DEFUN ("x-disown-selection-internal", Fx_disown_selection_internal,
- Sx_disown_selection_internal, 1, 2, 0,
- doc: /* If we own the selection SELECTION, disown it. */)
- (Lisp_Object selection_name, Lisp_Object time)
+ Sx_disown_selection_internal, 1, 3, 0,
+ doc: /* If we own the selection SELECTION, disown it.
+Disowning it means there is no such selection.
+
+Sets the last-change time for the selection to TIME-OBJECT (by default
+the time of the last event).
+
+TERMINAL should be a terminal object or a frame specifying the X
+server to query. If omitted or nil, that stands for the selected
+frame's display, or the first available X display.
+
+On Nextstep, the TIME-OBJECT and TERMINAL arguments are unused.
+On MS-DOS, all this does is return non-nil if we own the selection. */)
+ (Lisp_Object selection, Lisp_Object time_object, Lisp_Object terminal)
{
id pb;
check_ns ();
- CHECK_SYMBOL (selection_name);
- if (NILP (assq_no_quit (selection_name, Vselection_alist))) return Qnil;
+ CHECK_SYMBOL (selection);
+ if (NILP (assq_no_quit (selection, Vselection_alist))) return Qnil;
- pb =[NSPasteboard pasteboardWithName: symbol_to_nsstring (selection_name)];
- ns_undeclare_pasteboard (pb);
+ pb = ns_symbol_to_pb (selection);
+ if (pb != nil) ns_undeclare_pasteboard (pb);
return Qt;
}
DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p,
- 0, 1, 0, doc: /* Whether there is an owner for the given selection.
-The arg should be the name of the selection in question, typically one of
-the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
-\(Those are literal upper-case symbol names.)
-For convenience, the symbol nil is the same as `PRIMARY',
-and t is the same as `SECONDARY'.) */)
- (Lisp_Object selection)
+ 0, 2, 0, doc: /* Whether there is an owner for the given X selection.
+SELECTION should be the name of the selection in question, typically
+one of the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'. (X expects
+these literal upper-case names.) The symbol nil is the same as
+`PRIMARY', and t is the same as `SECONDARY'.
+
+TERMINAL should be a terminal object or a frame specifying the X
+server to query. If omitted or nil, that stands for the selected
+frame's display, or the first available X display.
+
+On Nextstep, TERMINAL is unused. */)
+ (Lisp_Object selection, Lisp_Object terminal)
{
id pb;
NSArray *types;
CHECK_SYMBOL (selection);
if (EQ (selection, Qnil)) selection = QPRIMARY;
if (EQ (selection, Qt)) selection = QSECONDARY;
- pb =[NSPasteboard pasteboardWithName: symbol_to_nsstring (selection)];
- types =[pb types];
+ pb = ns_symbol_to_pb (selection);
+ if (pb == nil) return Qnil;
+
+ types = [pb types];
return ([types count] == 0) ? Qnil : Qt;
}
DEFUN ("x-selection-owner-p", Fx_selection_owner_p, Sx_selection_owner_p,
- 0, 1, 0,
- doc: /* Whether the current Emacs process owns the given selection.
+ 0, 2, 0,
+ doc: /* Whether the current Emacs process owns the given X Selection.
The arg should be the name of the selection in question, typically one of
the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.
-\(Those are literal upper-case symbol names.)
+\(Those are literal upper-case symbol names, since that's what X expects.)
For convenience, the symbol nil is the same as `PRIMARY',
-and t is the same as `SECONDARY'.) */)
- (Lisp_Object selection)
+and t is the same as `SECONDARY'.
+
+TERMINAL should be a terminal object or a frame specifying the X
+server to query. If omitted or nil, that stands for the selected
+frame's display, or the first available X display.
+
+On Nextstep, TERMINAL is unused. */)
+ (Lisp_Object selection, Lisp_Object terminal)
{
check_ns ();
CHECK_SYMBOL (selection);
DEFUN ("x-get-selection-internal", Fx_get_selection_internal,
- Sx_get_selection_internal, 2, 2, 0,
- doc: /* Return text selected from some pasteboard.
-SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
-\(Those are literal upper-case symbol names.)
-TYPE is the type of data desired, typically `STRING'. */)
- (Lisp_Object selection_name, Lisp_Object target_type)
+ Sx_get_selection_internal, 2, 4, 0,
+ doc: /* Return text selected from some X window.
+SELECTION-SYMBOL is typically `PRIMARY', `SECONDARY', or `CLIPBOARD'.
+\(Those are literal upper-case symbol names, since that's what X expects.)
+TARGET-TYPE is the type of data desired, typically `STRING'.
+
+TIME-STAMP is the time to use in the XConvertSelection call for foreign
+selections. If omitted, defaults to the time for the last event.
+
+TERMINAL should be a terminal object or a frame specifying the X
+server to query. If omitted or nil, that stands for the selected
+frame's display, or the first available X display.
+
+On Nextstep, TIME-STAMP and TERMINAL are unused. */)
+ (Lisp_Object selection_name, Lisp_Object target_type,
+ Lisp_Object time_stamp, Lisp_Object terminal)
{
Lisp_Object val;
}
-#ifdef CUT_BUFFER_SUPPORT
-DEFUN ("ns-get-cut-buffer-internal", Fns_get_cut_buffer_internal,
- Sns_get_cut_buffer_internal, 1, 1, 0,
- doc: /* Returns the value of the named cut buffer. */)
- (Lisp_Object buffer)
+DEFUN ("ns-get-selection-internal", Fns_get_selection_internal,
+ Sns_get_selection_internal, 1, 1, 0,
+ doc: /* Returns the value of SELECTION as a string.
+SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. */)
+ (Lisp_Object selection)
{
id pb;
check_ns ();
- pb =[NSPasteboard pasteboardWithName: symbol_to_nsstring (buffer)];
- return ns_string_from_pasteboard (pb);
+ pb = ns_symbol_to_pb (selection);
+ return pb != nil ? ns_string_from_pasteboard (pb) : Qnil;
}
-DEFUN ("ns-rotate-cut-buffers-internal", Fns_rotate_cut_buffers_internal,
- Sns_rotate_cut_buffers_internal, 1, 1, 0,
- doc: /* Rotate the values of the cut buffers by N steps.
-Positive N means move values forward, negative means
-backward. CURRENTLY NOT IMPLEMENTED UNDER NEXTSTEP. */ )
- (Lisp_Object n)
-{
- /* XXX This function is unimplemented under NeXTstep XXX */
- Fsignal (Qquit, Fcons (build_string (
- "Warning: ns-rotate-cut-buffers-internal not implemented\n"), Qnil));
- return Qnil;
-}
-
-
-DEFUN ("ns-store-cut-buffer-internal", Fns_store_cut_buffer_internal,
- Sns_store_cut_buffer_internal, 2, 2, 0,
- doc: /* Sets the value of the named cut buffer (typically CUT_BUFFER0). */)
- (Lisp_Object buffer, Lisp_Object string)
+DEFUN ("ns-store-selection-internal", Fns_store_selection_internal,
+ Sns_store_selection_internal, 2, 2, 0,
+ doc: /* Sets the string value of SELECTION.
+SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. */)
+ (Lisp_Object selection, Lisp_Object string)
{
id pb;
check_ns ();
- pb =[NSPasteboard pasteboardWithName: symbol_to_nsstring (buffer)];
- ns_string_to_pasteboard (pb, string);
+ pb = ns_symbol_to_pb (selection);
+ if (pb != nil) ns_string_to_pasteboard (pb, string);
return Qnil;
}
-#endif
void
defsubr (&Sx_own_selection_internal);
defsubr (&Sx_selection_exists_p);
defsubr (&Sx_selection_owner_p);
-#ifdef CUT_BUFFER_SUPPORT
- defsubr (&Sns_get_cut_buffer_internal);
- defsubr (&Sns_rotate_cut_buffers_internal);
- defsubr (&Sns_store_cut_buffer_internal);
-#endif
+ defsubr (&Sns_get_selection_internal);
+ defsubr (&Sns_store_selection_internal);
Vselection_alist = Qnil;
staticpro (&Vselection_alist);