X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/17fdb2228b820dc577ff61b03876117eba5226d1..fb39b937b0628f4592b07d0aa61a41cf696abd30:/src/nsselect.m diff --git a/src/nsselect.m b/src/nsselect.m index 9f6f35968f..95bc1a9595 100644 --- a/src/nsselect.m +++ b/src/nsselect.m @@ -1,5 +1,5 @@ /* 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. @@ -28,15 +28,12 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu) /* This should be the first include, as it may set up #defines affecting interpretation of even the system includes. */ #include -#include #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; @@ -60,13 +57,18 @@ static NSString * 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) @@ -154,7 +156,7 @@ ns_string_to_pasteboard_internal (id pb, Lisp_Object str, NSString *gtype) CHECK_STRING (str); - utfStr = SDATA (str); + utfStr = SSDATA (str); nsStr = [[NSString alloc] initWithBytesNoCopy: utfStr length: SBYTES (str) encoding: NSUTF8StringEncoding @@ -230,70 +232,11 @@ static Lisp_Object 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); - } -} - /* ========================================================================== @@ -392,66 +335,103 @@ ns_string_to_pasteboard (id pb, Lisp_Object str) 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; @@ -460,21 +440,29 @@ and t is the same as `SECONDARY'.) */) 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); @@ -485,12 +473,22 @@ and t is the same as `SECONDARY'.) */) 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; @@ -511,45 +509,31 @@ TYPE is the type of data desired, typically `STRING'. */) } -#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 @@ -572,11 +556,8 @@ syms_of_nsselect (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);