From c803b2b767f8ed06beb28106a03f23bc577cfdae Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20Dj=C3=A4rv?= Date: Sun, 18 Dec 2011 14:49:38 +0100 Subject: [PATCH] NS selection bug fix and cleanup, see thread C-g crash in C-x C-f (OSX Lion). Thread is on emacs-devel. * lisp/term/ns-win.el (ns-get-selection-internal) (ns-store-selection-internal): Declare. (ns-store-cut-buffer-internal, ns-get-cut-buffer-internal): Declare as obsolete. (ns-get-pasteboard, ns-paste-secondary): Use ns-get-selection-internal. (ns-set-pasteboard, ns-copy-including-secondary): Use ns-store-selection-internal. * src/nsselect.m (CUT_BUFFER_SUPPORT): Remove define. (symbol_to_nsstring): Fix indentation. (ns_symbol_to_pb): New function. (Fns_get_selection_internal): Renamed from Fns_get_cut_buffer_internal. (Fns_rotate_cut_buffers_internal): Removed. (Fns_store_selection_internal): Renamed from Fns_store_cut_buffer_internal. (ns_get_foreign_selection, Fx_own_selection_internal) (Fx_disown_selection_internal, Fx_selection_exists_p) (Fns_get_selection_internal, Fns_store_selection_internal): Use ns_symbol_to_pb and check if return value is nil. (syms_of_nsselect): Remove ifdef CUT_BUFFER_SUPPORT. Remove defsubr Sns_rotate_cut_buffers_internal. Sns_get_cut_buffer_internal renamed to Sns_get_selection_internal, Sns_store_cut_buffer_internal renamed to Sns_store_selection_internal. (ns_handle_selection_request): Move code to Fx_own_selection_internal and remove this function. (ns_handle_selection_clear): Remove, never used. (Fx_own_selection_internal): Move code from ns_handle_selection_request here. --- lisp/ChangeLog | 11 +++ lisp/term/ns-win.el | 21 +++--- src/ChangeLog | 23 ++++++ src/nsselect.m | 168 +++++++++++++++----------------------------- 4 files changed, 103 insertions(+), 120 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 990a7259bc8..9be0d2f1a3c 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,14 @@ +2011-12-18 Jan Djärv + + * term/ns-win.el (ns-get-selection-internal) + (ns-store-selection-internal): Declare. + (ns-store-cut-buffer-internal, ns-get-cut-buffer-internal): Declare + as obsolete. + (ns-get-pasteboard, ns-paste-secondary): Use + ns-get-selection-internal. + (ns-set-pasteboard, ns-copy-including-secondary): Use + ns-store-selection-internal. + 2011-12-17 Chong Yidong * vc/vc.el (vc-next-action): Doc fix; remove CVS-isms. diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el index b639af7cda0..df0ddd7de8b 100644 --- a/lisp/term/ns-win.el +++ b/lisp/term/ns-win.el @@ -702,19 +702,24 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.") ;;;; Pasteboard support. -(declare-function ns-get-cut-buffer-internal "nsselect.m" (buffer)) +(declare-function ns-get-selection-internal "nsselect.m" (buffer)) +(declare-function ns-store-selection-internal "nsselect.m" (buffer string)) + +(define-obsolete-function-alias 'ns-get-cut-buffer-internal + 'ns-get-selection-internal "24.1") +(define-obsolete-function-alias 'ns-store-cut-buffer-internal + 'ns-store-selection-internal "24.1") + (defun ns-get-pasteboard () "Returns the value of the pasteboard." - (ns-get-cut-buffer-internal 'CLIPBOARD)) - -(declare-function ns-store-cut-buffer-internal "nsselect.m" (buffer string)) + (ns-get-selection-internal 'CLIPBOARD)) (defun ns-set-pasteboard (string) "Store STRING into the pasteboard of the Nextstep display server." ;; Check the data type of STRING. (if (not (stringp string)) (error "Nonstring given to pasteboard")) - (ns-store-cut-buffer-internal 'CLIPBOARD string)) + (ns-store-selection-internal 'CLIPBOARD string)) ;; We keep track of the last text selected here, so we can check the ;; current selection against it, and avoid passing back our own text @@ -742,11 +747,11 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.") (defun ns-copy-including-secondary () (interactive) (call-interactively 'kill-ring-save) - (ns-store-cut-buffer-internal 'SECONDARY - (buffer-substring (point) (mark t)))) + (ns-store-selection-internal 'SECONDARY + (buffer-substring (point) (mark t)))) (defun ns-paste-secondary () (interactive) - (insert (ns-get-cut-buffer-internal 'SECONDARY))) + (insert (ns-get-selection-internal 'SECONDARY))) ;;;; Scrollbar handling. diff --git a/src/ChangeLog b/src/ChangeLog index e25f0c68ce0..610079fe321 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,26 @@ +2011-12-18 Jan Djärv + + * nsselect.m (CUT_BUFFER_SUPPORT): Remove define. + (symbol_to_nsstring): Fix indentation. + (ns_symbol_to_pb): New function. + (Fns_get_selection_internal): Renamed from Fns_get_cut_buffer_internal. + (Fns_rotate_cut_buffers_internal): Removed. + (Fns_store_selection_internal): Renamed from + Fns_store_cut_buffer_internal. + (ns_get_foreign_selection, Fx_own_selection_internal) + (Fx_disown_selection_internal, Fx_selection_exists_p) + (Fns_get_selection_internal, Fns_store_selection_internal): Use + ns_symbol_to_pb and check if return value is nil. + (syms_of_nsselect): Remove ifdef CUT_BUFFER_SUPPORT. Remove + defsubr Sns_rotate_cut_buffers_internal. Sns_get_cut_buffer_internal + renamed to Sns_get_selection_internal, Sns_store_cut_buffer_internal + renamed to Sns_store_selection_internal. + (ns_handle_selection_request): Move code to Fx_own_selection_internal + and remove this function. + (ns_handle_selection_clear): Remove, never used. + (Fx_own_selection_internal): Move code from ns_handle_selection_request + here. + 2011-12-17 Ken Brown * fileio.c (check_writable) [CYGWIN]: Return non-zero if UID or diff --git a/src/nsselect.m b/src/nsselect.m index 867cf3252e5..928eb8652dc 100644 --- a/src/nsselect.m +++ b/src/nsselect.m @@ -35,8 +35,6 @@ GNUstep port and post-20 update by Adrian Robert (arobert@cogsci.ucsd.edu) #include "termhooks.h" #include "keyboard.h" -#define CUT_BUFFER_SUPPORT - Lisp_Object QCLIPBOARD, QSECONDARY, QTEXT, QFILE_NAME; static Lisp_Object Vselection_alist; @@ -60,13 +58,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)]; } +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) @@ -230,70 +233,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); -} - - -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); - } + pb = ns_symbol_to_pb (symbol); + return pb != nil ? ns_string_from_pasteboard (pb) : Qnil; } -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); - } -} - /* ========================================================================== @@ -401,29 +345,44 @@ anything that the functions on `selection-converter-alist' know about. */) { 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)]; + pb = ns_symbol_to_pb (selection_name); + 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)); + 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); - } + + /* We only support copy of text. */ + type = NSStringPboardType; + target_symbol = ns_string_to_symbol (type); + 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); + } + return selection_value; } @@ -438,8 +397,8 @@ DEFUN ("x-disown-selection-internal", Fx_disown_selection_internal, CHECK_SYMBOL (selection_name); if (NILP (assq_no_quit (selection_name, Vselection_alist))) return Qnil; - pb =[NSPasteboard pasteboardWithName: symbol_to_nsstring (selection_name)]; - ns_undeclare_pasteboard (pb); + pb = ns_symbol_to_pb (selection_name); + if (pb != nil) ns_undeclare_pasteboard (pb); return Qt; } @@ -460,8 +419,10 @@ 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; } @@ -511,45 +472,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 +519,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); -- 2.39.2