]> code.delx.au - gnu-emacs/blobdiff - src/xselect.c
Merged from miles@gnu.org--gnu-2005 (patch 83-87, 449-468)
[gnu-emacs] / src / xselect.c
index f54e685873a162cef0020c80a030d82c52eefb7a..c60c12c3b673ae946b3611f24a4695f246f23a98 100644 (file)
@@ -397,13 +397,20 @@ x_own_selection (selection_name, selection_value)
      Lisp_Object selection_name, selection_value;
 {
   struct frame *sf = SELECTED_FRAME ();
-  Window selecting_window = FRAME_X_WINDOW (sf);
-  Display *display = FRAME_X_DISPLAY (sf);
+  Window selecting_window;
+  Display *display;
   Time time = last_event_timestamp;
   Atom selection_atom;
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (sf);
+  struct x_display_info *dpyinfo;
   int count;
 
+  if (! FRAME_X_P (sf))
+    return;
+
+  selecting_window = FRAME_X_WINDOW (sf);
+  display = FRAME_X_DISPLAY (sf);
+  dpyinfo = FRAME_X_DISPLAY_INFO (sf);
+  
   CHECK_SYMBOL (selection_name);
   selection_atom = symbol_to_x_atom (dpyinfo, display, selection_name);
 
@@ -664,7 +671,8 @@ some_frame_on_display (dpyinfo)
 
   FOR_EACH_FRAME (list, frame)
     {
-      if (FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
+      if (FRAME_X_P (XFRAME (frame))
+          && FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
        return frame;
     }
 
@@ -1002,7 +1010,7 @@ x_handle_selection_clear (event)
      to see if this Emacs job now owns the selection
      through that display.  */
   for (t_dpyinfo = x_display_list; t_dpyinfo; t_dpyinfo = t_dpyinfo->next)
-    if (t_dpyinfo->kboard == dpyinfo->kboard)
+    if (t_dpyinfo->frame_display->kboard == dpyinfo->frame_display->kboard)
       {
        Window owner_window
          = XGetSelectionOwner (t_dpyinfo->display, selection);
@@ -1362,17 +1370,26 @@ x_get_foreign_selection (selection_symbol, target_type, time_stamp)
      Lisp_Object selection_symbol, target_type, time_stamp;
 {
   struct frame *sf = SELECTED_FRAME ();
-  Window requestor_window = FRAME_X_WINDOW (sf);
-  Display *display = FRAME_X_DISPLAY (sf);
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (sf);
+  Window requestor_window;
+  Display *display;
+  struct x_display_info *dpyinfo;
   Time requestor_time = last_event_timestamp;
-  Atom target_property = dpyinfo->Xatom_EMACS_TMP;
-  Atom selection_atom = symbol_to_x_atom (dpyinfo, display, selection_symbol);
+  Atom target_property;
+  Atom selection_atom;
   Atom type_atom;
   int secs, usecs;
   int count;
   Lisp_Object frame;
 
+  if (! FRAME_X_P (sf))
+    return Qnil;
+
+  requestor_window = FRAME_X_WINDOW (sf);
+  display = FRAME_X_DISPLAY (sf);
+  dpyinfo = FRAME_X_DISPLAY_INFO (sf);
+  target_property = dpyinfo->Xatom_EMACS_TMP;
+  selection_atom = symbol_to_x_atom (dpyinfo, display, selection_symbol);
+
   if (CONSP (target_type))
     type_atom = symbol_to_x_atom (dpyinfo, display, XCAR (target_type));
   else
@@ -1769,7 +1786,11 @@ x_get_window_property_as_lisp_data (display, window, property, target_type,
 
    When converting an object to C, it may be of the form (SYMBOL . <data>)
    where SYMBOL is what we should claim that the type is.  Format and
-   representation are as above.  */
+   representation are as above.
+
+   Important: When format is 32, data should contain an array of int,
+   not an array of long as the X library returns.  This makes a difference
+   when sizeof(long) != sizeof(int).  */
 
 
 
@@ -1811,15 +1832,21 @@ selection_data_to_lisp_data (display, data, size, type, format)
   else if (type == XA_ATOM)
     {
       int i;
-      if (size == sizeof (Atom))
-       return x_atom_to_symbol (display, *((Atom *) data));
+      /* On a 64 bit machine sizeof(Atom) == sizeof(long) == 8.
+         But the callers of these function has made sure the data for
+         format == 32 is an array of int.  Thus, use int instead
+         of Atom.  */
+      int *idata = (int *) data;
+
+      if (size == sizeof (int))
+       return x_atom_to_symbol (display, (Atom) idata[0]);
       else
        {
-         Lisp_Object v = Fmake_vector (make_number (size / sizeof (Atom)),
+         Lisp_Object v = Fmake_vector (make_number (size / sizeof (int)),
                                        make_number (0));
-         for (i = 0; i < size / sizeof (Atom); i++)
+         for (i = 0; i < size / sizeof (int); i++)
            Faset (v, make_number (i),
-                  x_atom_to_symbol (display, ((Atom *) data) [i]));
+                   x_atom_to_symbol (display, (Atom) idata[i]));
          return v;
        }
     }
@@ -1898,7 +1925,12 @@ lisp_data_to_selection_data (display, obj,
     }
   else if (STRINGP (obj))
     {
-      xassert (! STRING_MULTIBYTE (obj));
+      if (SCHARS (obj) < SBYTES (obj))
+       /* OBJ is a multibyte string containing a non-ASCII char.  */
+       Fsignal (Qerror, /* Qselection_error */
+                Fcons (build_string
+                       ("Non-ASCII string must be encoded in advance"),
+                       Fcons (obj, Qnil)));
       if (NILP (type))
        type = QSTRING;
       *format_ret = 8;
@@ -2016,7 +2048,7 @@ lisp_data_to_selection_data (display, obj,
 
           /* Use sizeof(long) even if it is more than 32 bits.  See comment
              in x_get_window_property and x_fill_property_data.  */
-          
+
           if (*format_ret == 32) data_size = sizeof(long);
          *data_ret = (unsigned char *) xmalloc (*size_ret * data_size);
          for (i = 0; i < *size_ret; i++)
@@ -2030,7 +2062,7 @@ lisp_data_to_selection_data (display, obj,
     }
   else
     Fsignal (Qerror, /* Qselection_error */
-            Fcons (build_string ("unrecognised selection data"),
+            Fcons (build_string ("unrecognized selection data"),
                    Fcons (obj, Qnil)));
 
   *type_ret = symbol_to_x_atom (dpyinfo, display, type);
@@ -2104,7 +2136,7 @@ anything that the functions on `selection-converter-alist' know about.  */)
 {
   check_x ();
   CHECK_SYMBOL (selection_name);
-  if (NILP (selection_value)) error ("selection-value may not be nil");
+  if (NILP (selection_value)) error ("SELECTION-VALUE may not be nil");
   x_own_selection (selection_name, selection_value);
   return selection_value;
 }
@@ -2174,12 +2206,18 @@ Disowning it means there is no such selection.  */)
 {
   Time timestamp;
   Atom selection_atom;
-  struct selection_input_event event;
+  union {
+    struct selection_input_event sie;
+    struct input_event ie;
+  } event;
   Display *display;
   struct x_display_info *dpyinfo;
   struct frame *sf = SELECTED_FRAME ();
 
   check_x ();
+  if (! FRAME_X_P (sf))
+    return Qnil;
+
   display = FRAME_X_DISPLAY (sf);
   dpyinfo = FRAME_X_DISPLAY_INFO (sf);
   CHECK_SYMBOL (selection);
@@ -2202,10 +2240,10 @@ Disowning it means there is no such selection.  */)
      the selection owner to None.  The NCD server does, the MIT Sun4 server
      doesn't.  So we synthesize one; this means we might get two, but
      that's ok, because the second one won't have any effect.  */
-  SELECTION_EVENT_DISPLAY (&event) = display;
-  SELECTION_EVENT_SELECTION (&event) = selection_atom;
-  SELECTION_EVENT_TIME (&event) = timestamp;
-  x_handle_selection_clear ((struct input_event *) &event);
+  SELECTION_EVENT_DISPLAY (&event.sie) = display;
+  SELECTION_EVENT_SELECTION (&event.sie) = selection_atom;
+  SELECTION_EVENT_TIME (&event.sie) = timestamp;
+  x_handle_selection_clear (&event.ie);
 
   return Qt;
 }
@@ -2343,6 +2381,10 @@ DEFUN ("x-get-cut-buffer-internal", Fx_get_cut_buffer_internal,
   struct frame *sf = SELECTED_FRAME ();
 
   check_x ();
+
+  if (! FRAME_X_P (sf))
+    return Qnil;
+
   display = FRAME_X_DISPLAY (sf);
   dpyinfo = FRAME_X_DISPLAY_INFO (sf);
   window = RootWindow (display, 0); /* Cut buffers are on screen 0 */
@@ -2384,6 +2426,10 @@ DEFUN ("x-store-cut-buffer-internal", Fx_store_cut_buffer_internal,
   struct frame *sf = SELECTED_FRAME ();
 
   check_x ();
+
+  if (! FRAME_X_P (sf))
+    return Qnil;
+
   display = FRAME_X_DISPLAY (sf);
   window = RootWindow (display, 0); /* Cut buffers are on screen 0 */
 
@@ -2440,8 +2486,12 @@ Positive means shift the values forward, negative means backward.  */)
   Atom props[8];
   Display *display;
   struct frame *sf = SELECTED_FRAME ();
-
+  
   check_x ();
+
+  if (! FRAME_X_P (sf))
+    return Qnil;
+
   display = FRAME_X_DISPLAY (sf);
   window = RootWindow (display, 0); /* Cut buffers are on screen 0 */
   CHECK_NUMBER (n);
@@ -2560,6 +2610,10 @@ x_fill_property_data (dpy, data, ret, format)
    be stored in RET.
    SIZE is the number of elements in DATA.
 
+   Important: When format is 32, data should contain an array of int,
+   not an array of long as the X library returns.  This makes a difference
+   when sizeof(long) != sizeof(int).
+
    Also see comment for selection_data_to_lisp_data above.  */
 
 Lisp_Object
@@ -2810,7 +2864,7 @@ are ignored.  */)
      when sending to the root window.  */
   event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest;
 
-  
+
   memset (event.xclient.data.b, 0, sizeof (event.xclient.data.b));
   x_fill_property_data (dpyinfo->display, values, event.xclient.data.b,
                         event.xclient.format);