X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/9a0115abd18f219f234d6dd460cf7f5ed3c0332f..6d12ff8b3344d4284f78e0be56cda076f9a3d6e7:/src/xselect.c diff --git a/src/xselect.c b/src/xselect.c index 85c9c40cc3..5a3b7452c6 100644 --- a/src/xselect.c +++ b/src/xselect.c @@ -35,11 +35,11 @@ along with GNU Emacs. If not, see . */ #include "dispextern.h" /* frame.h seems to want this */ #include "frame.h" /* Need this to get the X window of selected_frame */ #include "blockinput.h" +#include "character.h" #include "buffer.h" #include "process.h" #include "termhooks.h" #include "keyboard.h" -#include "character.h" #include @@ -81,13 +81,13 @@ static Lisp_Object clean_local_selection_data (Lisp_Object); #ifdef TRACE_SELECTION #define TRACE0(fmt) \ - fprintf (stderr, "%d: " fmt "\n", getpid ()) + fprintf (stderr, "%"pMd": " fmt "\n", (printmax_t) getpid ()) #define TRACE1(fmt, a0) \ - fprintf (stderr, "%d: " fmt "\n", getpid (), a0) + fprintf (stderr, "%"pMd": " fmt "\n", (printmax_t) getpid (), a0) #define TRACE2(fmt, a0, a1) \ - fprintf (stderr, "%d: " fmt "\n", getpid (), a0, a1) + fprintf (stderr, "%"pMd": " fmt "\n", (printmax_t) getpid (), a0, a1) #define TRACE3(fmt, a0, a1, a2) \ - fprintf (stderr, "%d: " fmt "\n", getpid (), a0, a1, a2) + fprintf (stderr, "%"pMd": " fmt "\n", (printmax_t) getpid (), a0, a1, a2) #else #define TRACE0(fmt) (void) 0 #define TRACE1(fmt, a0) (void) 0 @@ -180,16 +180,11 @@ x_queue_event (struct input_event *event) } } - queue_tmp - = (struct selection_event_queue *) xmalloc (sizeof (struct selection_event_queue)); - - if (queue_tmp != NULL) - { - TRACE1 ("QUEUE SELECTION EVENT %p", queue_tmp); - queue_tmp->event = *event; - queue_tmp->next = selection_queue; - selection_queue = queue_tmp; - } + queue_tmp = xmalloc (sizeof *queue_tmp); + TRACE1 ("QUEUE SELECTION EVENT %p", queue_tmp); + queue_tmp->event = *event; + queue_tmp->next = selection_queue; + selection_queue = queue_tmp; } /* Start queuing SELECTION_REQUEST_EVENT events. */ @@ -198,7 +193,7 @@ static void x_start_queuing_selection_requests (void) { if (x_queue_selection_requests) - abort (); + emacs_abort (); x_queue_selection_requests++; TRACE1 ("x_start_queuing_selection_requests %d", x_queue_selection_requests); @@ -221,7 +216,7 @@ x_stop_queuing_selection_requests (void) TRACE1 ("RESTORE SELECTION EVENT %p", queue_tmp); kbd_buffer_unget_event (&queue_tmp->event); selection_queue = queue_tmp->next; - xfree ((char *)queue_tmp); + xfree (queue_tmp); } } @@ -250,7 +245,7 @@ symbol_to_x_atom (struct x_display_info *dpyinfo, Lisp_Object sym) if (EQ (sym, QEMACS_TMP)) return dpyinfo->Xatom_EMACS_TMP; if (EQ (sym, QTARGETS)) return dpyinfo->Xatom_TARGETS; if (EQ (sym, QNULL)) return dpyinfo->Xatom_NULL; - if (!SYMBOLP (sym)) abort (); + if (!SYMBOLP (sym)) emacs_abort (); TRACE1 (" XInternAtom %s", SSDATA (SYMBOL_NAME (sym))); BLOCK_INPUT; @@ -358,8 +353,9 @@ x_own_selection (Lisp_Object selection_name, Lisp_Object selection_value, INTEGER_TO_CONS (timestamp), frame); prev_value = LOCAL_SELECTION (selection_name, dpyinfo); - dpyinfo->terminal->Vselection_alist - = Fcons (selection_data, dpyinfo->terminal->Vselection_alist); + tset_selection_alist + (dpyinfo->terminal, + Fcons (selection_data, dpyinfo->terminal->Vselection_alist)); /* If we already owned the selection, remove the old selection data. Don't use Fdelq as that may QUIT. */ @@ -392,7 +388,6 @@ x_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type, { Lisp_Object local_value; Lisp_Object handler_fn, value, check; - int count; local_value = LOCAL_SELECTION (selection_symbol, dpyinfo); @@ -409,7 +404,7 @@ x_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type, /* Don't allow a quit within the converter. When the user types C-g, he would be surprised if by luck it came during a converter. */ - count = SPECPDL_INDEX (); + ptrdiff_t count = SPECPDL_INDEX (); specbind (Qinhibit_quit, Qt); CHECK_SYMBOL (target_type); @@ -603,7 +598,7 @@ x_reply_selection_request (struct input_event *event, Window window = SELECTION_EVENT_REQUESTOR (event); ptrdiff_t bytes_remaining; int max_bytes = selection_quantum (display); - int count = SPECPDL_INDEX (); + ptrdiff_t count = SPECPDL_INDEX (); struct selection_data *cs; reply->type = SelectionNotify; @@ -792,7 +787,7 @@ x_handle_selection_request (struct input_event *event) Atom property = SELECTION_EVENT_PROPERTY (event); Lisp_Object local_selection_data; int success = 0; - int count = SPECPDL_INDEX (); + ptrdiff_t count = SPECPDL_INDEX (); GCPRO2 (local_selection_data, target_symbol); if (!dpyinfo) goto DONE; @@ -913,7 +908,7 @@ x_convert_selection (struct input_event *event, Lisp_Object selection_symbol, { if (for_multiple) { - cs = xmalloc (sizeof (struct selection_data)); + cs = xmalloc (sizeof *cs); cs->data = (unsigned char *) &conversion_fail_tag; cs->size = 1; cs->format = 32; @@ -930,7 +925,8 @@ x_convert_selection (struct input_event *event, Lisp_Object selection_symbol, } /* Otherwise, record the converted selection to binary. */ - cs = xmalloc (sizeof (struct selection_data)); + cs = xmalloc (sizeof *cs); + cs->data = NULL; cs->nofree = 1; cs->property = property; cs->wait_object = NULL; @@ -994,7 +990,7 @@ x_handle_selection_clear (struct input_event *event) break; } } - dpyinfo->terminal->Vselection_alist = Vselection_alist; + tset_selection_alist (dpyinfo->terminal, Vselection_alist); /* Run the `x-lost-selection-functions' abnormal hook. */ { @@ -1044,7 +1040,7 @@ x_clear_frame_selections (FRAME_PTR f) args[1] = Fcar (Fcar (t->Vselection_alist)); Frun_hook_with_args (2, args); - t->Vselection_alist = XCDR (t->Vselection_alist); + tset_selection_alist (t, XCDR (t->Vselection_alist)); } /* Delete elements after the beginning of Vselection_alist. */ @@ -1085,7 +1081,7 @@ static struct prop_location * expect_property_change (Display *display, Window window, Atom property, int state) { - struct prop_location *pl = (struct prop_location *) xmalloc (sizeof *pl); + struct prop_location *pl = xmalloc (sizeof *pl); pl->identifier = ++prop_location_identifier; pl->display = display; pl->window = window; @@ -1139,11 +1135,10 @@ wait_for_property_change_unwind (Lisp_Object loc) static void wait_for_property_change (struct prop_location *location) { - int secs, usecs; - int count = SPECPDL_INDEX (); + ptrdiff_t count = SPECPDL_INDEX (); if (property_change_reply_object) - abort (); + emacs_abort (); /* Make sure to do unexpect_property_change if we quit or err. */ record_unwind_protect (wait_for_property_change_unwind, @@ -1156,10 +1151,11 @@ wait_for_property_change (struct prop_location *location) property_change_reply, because property_change_reply_object says so. */ if (! location->arrived) { - secs = x_selection_timeout / 1000; - usecs = (x_selection_timeout % 1000) * 1000; - TRACE2 (" Waiting %d secs, %d usecs", secs, usecs); - wait_reading_process_output (secs, usecs, 0, 0, + EMACS_INT timeout = max (0, x_selection_timeout); + EMACS_INT secs = timeout / 1000; + int nsecs = (timeout % 1000) * 1000000; + TRACE2 (" Waiting %"pI"d secs, %d nsecs", secs, nsecs); + wait_reading_process_output (secs, nsecs, 0, 0, property_change_reply, NULL, 0); if (NILP (XCAR (property_change_reply))) @@ -1228,7 +1224,8 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type, Atom type_atom = (CONSP (target_type) ? symbol_to_x_atom (dpyinfo, XCAR (target_type)) : symbol_to_x_atom (dpyinfo, target_type)); - int secs, usecs; + EMACS_INT timeout, secs; + int nsecs; if (!FRAME_LIVE_P (f)) return Qnil; @@ -1264,10 +1261,11 @@ x_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type, UNBLOCK_INPUT; /* This allows quits. Also, don't wait forever. */ - secs = x_selection_timeout / 1000; - usecs = (x_selection_timeout % 1000) * 1000; - TRACE1 (" Start waiting %d secs for SelectionNotify", secs); - wait_reading_process_output (secs, usecs, 0, 0, + timeout = max (0, x_selection_timeout); + secs = timeout / 1000; + nsecs = (timeout % 1000) * 1000000; + TRACE1 (" Start waiting %"pI"d secs for SelectionNotify", secs); + wait_reading_process_output (secs, nsecs, 0, 0, reading_selection_reply, NULL, 0); TRACE1 (" Got event = %d", !NILP (XCAR (reading_selection_reply))); @@ -1324,7 +1322,7 @@ x_get_window_property (Display *display, Window window, Atom property, goto done; /* This was allocated by Xlib, so use XFree. */ - XFree ((char *) tmp_data); + XFree (tmp_data); if (*actual_type_ret == None || *actual_format_ret == 0) goto done; @@ -1357,7 +1355,7 @@ x_get_window_property (Display *display, Window window, Atom property, break; bytes_per_item = *actual_format_ret >> 3; - xassert (*actual_size_ret <= buffer_size / bytes_per_item); + eassert (*actual_size_ret <= buffer_size / bytes_per_item); /* The man page for XGetWindowProperty says: "If the returned format is 32, the returned data is represented @@ -1406,7 +1404,7 @@ x_get_window_property (Display *display, Window window, Atom property, offset += bytes_gotten; /* This was allocated by Xlib, so use XFree. */ - XFree ((char *) tmp_data); + XFree (tmp_data); } XFlush (display); @@ -1444,7 +1442,7 @@ receive_incremental_selection (Display *display, Window window, Atom property, struct prop_location *wait_object; if (min (PTRDIFF_MAX, SIZE_MAX) < min_size_bytes) memory_full (SIZE_MAX); - *data_ret = (unsigned char *) xmalloc (min_size_bytes); + *data_ret = xmalloc (min_size_bytes); *size_bytes_ret = min_size_bytes; TRACE1 ("Read %u bytes incrementally", min_size_bytes); @@ -1571,7 +1569,7 @@ x_get_window_property_as_lisp_data (Display *display, Window window, BLOCK_INPUT; /* Use xfree, not XFree, because x_get_window_property calls xmalloc itself. */ - xfree ((char *) data); + xfree (data); UNBLOCK_INPUT; receive_incremental_selection (display, window, property, target_type, min_size_bytes, &data, &bytes, @@ -1592,7 +1590,7 @@ x_get_window_property_as_lisp_data (Display *display, Window window, /* Use xfree, not XFree, because x_get_window_property calls xmalloc itself. */ - xfree ((char *) data); + xfree (data); return val; } @@ -1701,7 +1699,7 @@ selection_data_to_lisp_data (Display *display, const unsigned char *data, v = Fmake_vector (make_number (size / 2), make_number (0)); for (i = 0; i < size / 2; i++) { - EMACS_INT j = ((short *) data) [i]; + short j = ((short *) data) [i]; Faset (v, make_number (i), make_number (j)); } return v; @@ -1778,20 +1776,24 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj, } else if (SYMBOLP (obj)) { - *data_ret = (unsigned char *) xmalloc (sizeof (Atom) + 1); + void *data = xmalloc (sizeof (Atom) + 1); + Atom *x_atom_ptr = data; + *data_ret = data; *format_ret = 32; *size_ret = 1; (*data_ret) [sizeof (Atom)] = 0; - (*(Atom **) data_ret) [0] = symbol_to_x_atom (dpyinfo, obj); + *x_atom_ptr = symbol_to_x_atom (dpyinfo, obj); if (NILP (type)) type = QATOM; } else if (RANGED_INTEGERP (X_SHRT_MIN, obj, X_SHRT_MAX)) { - *data_ret = (unsigned char *) xmalloc (sizeof (short) + 1); + void *data = xmalloc (sizeof (short) + 1); + short *short_ptr = data; + *data_ret = data; *format_ret = 16; *size_ret = 1; (*data_ret) [sizeof (short)] = 0; - (*(short **) data_ret) [0] = XINT (obj); + *short_ptr = XINT (obj); if (NILP (type)) type = QINTEGER; } else if (INTEGERP (obj) @@ -1800,11 +1802,13 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj, || (CONSP (XCDR (obj)) && INTEGERP (XCAR (XCDR (obj))))))) { - *data_ret = (unsigned char *) xmalloc (sizeof (unsigned long) + 1); + void *data = xmalloc (sizeof (unsigned long) + 1); + unsigned long *x_long_ptr = data; + *data_ret = data; *format_ret = 32; *size_ret = 1; (*data_ret) [sizeof (unsigned long)] = 0; - (*(unsigned long **) data_ret) [0] = cons_to_x_long (obj); + *x_long_ptr = cons_to_x_long (obj); if (NILP (type)) type = QINTEGER; } else if (VECTORP (obj)) @@ -1816,30 +1820,35 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj, ptrdiff_t i; ptrdiff_t size = ASIZE (obj); - if (SYMBOLP (XVECTOR (obj)->contents [0])) + if (SYMBOLP (AREF (obj, 0))) /* This vector is an ATOM set */ { + void *data; + Atom *x_atoms; if (NILP (type)) type = QATOM; for (i = 0; i < size; i++) - if (!SYMBOLP (XVECTOR (obj)->contents [i])) + if (!SYMBOLP (AREF (obj, i))) signal_error ("All elements of selection vector must have same type", obj); - *data_ret = xnmalloc (size, sizeof (Atom)); + *data_ret = data = xnmalloc (size, sizeof *x_atoms); + x_atoms = data; *format_ret = 32; *size_ret = size; for (i = 0; i < size; i++) - (*(Atom **) data_ret) [i] - = symbol_to_x_atom (dpyinfo, XVECTOR (obj)->contents [i]); + x_atoms[i] = symbol_to_x_atom (dpyinfo, AREF (obj, i)); } else /* This vector is an INTEGER set, or something like it */ { int format = 16; int data_size = sizeof (short); + void *data; + unsigned long *x_atoms; + short *shorts; if (NILP (type)) type = QINTEGER; for (i = 0; i < size; i++) { - if (! RANGED_INTEGERP (X_SHRT_MIN, XVECTOR (obj)->contents[i], + if (! RANGED_INTEGERP (X_SHRT_MIN, AREF (obj, i), X_SHRT_MAX)) { /* Use sizeof (long) even if it is more than 32 bits. @@ -1850,17 +1859,17 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj, break; } } - *data_ret = xnmalloc (size, data_size); + *data_ret = data = xnmalloc (size, data_size); + x_atoms = data; + shorts = data; *format_ret = format; *size_ret = size; for (i = 0; i < size; i++) { if (format == 32) - (*((unsigned long **) data_ret)) [i] = - cons_to_x_long (XVECTOR (obj)->contents[i]); + x_atoms[i] = cons_to_x_long (AREF (obj, i)); else - (*((short **) data_ret)) [i] = - XINT (XVECTOR (obj)->contents[i]); + shorts[i] = XINT (AREF (obj, i)); } } } @@ -1895,11 +1904,10 @@ clean_local_selection_data (Lisp_Object obj) ptrdiff_t size = ASIZE (obj); Lisp_Object copy; if (size == 1) - return clean_local_selection_data (XVECTOR (obj)->contents [0]); + return clean_local_selection_data (AREF (obj, 0)); copy = Fmake_vector (make_number (size), Qnil); for (i = 0; i < size; i++) - XVECTOR (copy)->contents [i] - = clean_local_selection_data (XVECTOR (obj)->contents [i]); + ASET (copy, i, clean_local_selection_data (AREF (obj, i))); return copy; } return obj; @@ -1982,7 +1990,9 @@ VALUE is typically a string, or a cons of two markers, but may be 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. */) +nil, it defaults to the selected frame. + +On Nextstep, FRAME is unused. */) (Lisp_Object selection, Lisp_Object value, Lisp_Object frame) { if (NILP (frame)) frame = selected_frame; @@ -2003,15 +2013,18 @@ nil, it defaults to the selected frame. */) DEFUN ("x-get-selection-internal", Fx_get_selection_internal, Sx_get_selection_internal, 2, 4, 0, doc: /* Return text selected from some X window. -SELECTION is a symbol, typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. +SELECTION-SYMBOL is typically `PRIMARY', `SECONDARY', or `CLIPBOARD'. \(Those are literal upper-case symbol names, since that's what X expects.) -TYPE is the type of data desired, typically `STRING'. -TIME_STAMP is the time to use in the XConvertSelection call for foreign +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. */) +frame's display, or the first available X display. + +On Nextstep, TIME-STAMP and TERMINAL are unused. */) (Lisp_Object selection_symbol, Lisp_Object target_type, Lisp_Object time_stamp, Lisp_Object terminal) { @@ -2052,9 +2065,15 @@ DEFUN ("x-disown-selection-internal", Fx_disown_selection_internal, 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. */) +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) { Time timestamp; @@ -2110,7 +2129,9 @@ 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. */) +frame's display, or the first available X display. + +On Nextstep, TERMINAL is unused. */) (Lisp_Object selection, Lisp_Object terminal) { struct frame *f = frame_for_x_selection (terminal); @@ -2129,13 +2150,15 @@ DEFUN ("x-selection-exists-p", Fx_selection_exists_p, Sx_selection_exists_p, 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'. +one of the symbols `PRIMARY', `SECONDARY', `CLIPBOARD', or +`CLIPBOARD_MANAGER' (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. */) +frame's display, or the first available X display. + +On Nextstep, TERMINAL is unused. */) (Lisp_Object selection, Lisp_Object terminal) { Window owner; @@ -2258,8 +2281,14 @@ x_clipboard_manager_save_all (void) local_frame = XCAR (XCDR (XCDR (XCDR (local_selection)))); if (FRAME_LIVE_P (XFRAME (local_frame))) - internal_condition_case_1 (x_clipboard_manager_save, local_frame, - Qt, x_clipboard_manager_error_2); + { + Lisp_Object args[1]; + args[0] = build_string ("Saving clipboard to X clipboard manager..."); + Fmessage (1, args); + + internal_condition_case_1 (x_clipboard_manager_save, local_frame, + Qt, x_clipboard_manager_error_2); + } } } @@ -2601,13 +2630,12 @@ x_send_client_event (Lisp_Object display, Lisp_Object dest, Lisp_Object from, if (x_check_property_data (values) == -1) error ("Bad data in VALUES, must be number, cons or string"); - event.xclient.type = ClientMessage; - event.xclient.format = XFASTINT (format); - - if (event.xclient.format != 8 && event.xclient.format != 16 - && event.xclient.format != 32) + if (XINT (format) != 8 && XINT (format) != 16 && XINT (format) != 32) error ("FORMAT must be one of 8, 16 or 32"); + event.xclient.type = ClientMessage; + event.xclient.format = XINT (format); + if (FRAMEP (dest) || NILP (dest)) { struct frame *fdest = check_x_frame (dest);