XEmacs 21.2.33 "Melpomene".
[chise/xemacs-chise.git.1] / src / select-msw.c
index 2e4a127..7d11bd9 100644 (file)
@@ -29,162 +29,183 @@ Boston, MA 02111-1307, USA.  */
 
 #include <config.h>
 #include "lisp.h"
+#include "frame.h"
 #include "select.h"
 
 #include "console-msw.h"
 
-DEFUN ("mswindows-set-clipboard", Fmswindows_set_clipboard, 1, 1, 0, /*
-Copy STRING to the mswindows clipboard.
-*/
-       (string))
-{
-  int rawsize, size, i;
-  unsigned char *src, *dst, *next;
-  HGLOBAL h = NULL;
-
-  CHECK_STRING (string);
-
-  /* Calculate size with LFs converted to CRLFs because
-   * CF_TEXT format uses CRLF delimited ASCIIZ */
-  src = XSTRING_DATA (string);
-  size = rawsize = XSTRING_LENGTH (string) + 1;
-  for (i=0; i<rawsize; i++)
-    if (src[i] == '\n')
-      size++;
-
-  if (!OpenClipboard (NULL))
-    return Qnil;
-
-  if (!EmptyClipboard () ||
-      (h = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, size)) == NULL ||
-      (dst = (unsigned char *) GlobalLock (h)) == NULL)
-    {
-      if (h != NULL) GlobalFree (h);
-      CloseClipboard ();
-      return Qnil;
-    }
-    
-  /* Convert LFs to CRLFs */
-  do
-    {
-      /* copy next line or remaining bytes including '\0' */
-      next = memccpy (dst, src, '\n', rawsize);
-      if (next)
-       {
-         /* copied one line ending with '\n' */
-         int copied = next - dst;
-         rawsize -= copied;
-         src += copied;
-         /* insert '\r' before '\n' */
-         next[-1] = '\r';
-         next[0] = '\n';
-         dst = next+1;
-       }           
-    }
-  while (next);
-    
-  GlobalUnlock (h);
-  
-  i = (SetClipboardData (CF_TEXT, h) != NULL);
-  
-  CloseClipboard ();
-  GlobalFree (h);
-  
-  return i ? Qt : Qnil;
-}
 
 /* Do protocol to assert ourself as a selection owner. Under mswindows
 this is easy, we just set the clipboard.  */
 static Lisp_Object
-mswindows_own_selection (Lisp_Object selection_name, Lisp_Object selection_value)
+mswindows_own_selection (Lisp_Object selection_name,
+                        Lisp_Object selection_value)
 {
   Lisp_Object converted_value = get_local_selection (selection_name, QSTRING);
+
   if (!NILP (converted_value) &&
       CONSP (converted_value) &&
-      EQ (XCAR (converted_value), QSTRING))
-    Fmswindows_set_clipboard (XCDR (converted_value));
+      EQ (XCAR (converted_value), QSTRING) &&
+      /* pure mswindows behaviour only says we can own the selection 
+        if it is the clipboard */
+      EQ (selection_name, QCLIPBOARD))
+    {
+      int rawsize, size, i;
+      unsigned char *src, *dst, *next;
+      HGLOBAL h = NULL;
+      struct frame *f = NULL;
+      struct gcpro gcpro1, gcpro2;
+      Lisp_Object string = XCDR (converted_value);
 
-  return Qnil;
-}
+      GCPRO2 (converted_value, string);
 
-DEFUN ("mswindows-get-clipboard", Fmswindows_get_clipboard, 0, 0, 0, /*
-Return the contents of the mswindows clipboard.
-*/
-       ())
-{
-  HANDLE h;
-  unsigned char *src, *dst, *next;
-  Lisp_Object ret = Qnil;
+      CHECK_STRING (string);
 
-  if (!OpenClipboard (NULL))
-    return Qnil;
+      /* Calculate size with LFs converted to CRLFs because
+       * CF_TEXT format uses CRLF delimited ASCIIZ */
+      src = XSTRING_DATA (string);
+      size = rawsize = XSTRING_LENGTH (string) + 1;
+      for (i=0; i<rawsize; i++)
+       if (src[i] == '\n')
+         size++;
 
-  if ((h = GetClipboardData (CF_TEXT)) != NULL &&
-      (src = (unsigned char *) GlobalLock (h)) != NULL)
-    {
-      int i;
-      int size, rawsize;
-      size = rawsize = strlen (src);
+      f = selected_frame ();
+      if (!OpenClipboard (FRAME_MSWINDOWS_HANDLE (f)))
+       {
+         UNGCPRO;
+         return Qnil;
+       }
 
-      for (i=0; i<rawsize; i++)
-       if (src[i] == '\r' && src[i+1] == '\n')
-         size--;
+      /* This call to EmptyClipboard may post an event back to us if
+        we already own the clipboard (to tell us we lost it) and this
+        event may execute random lisp code.  Hence we must protect
+        the string and get its address again after the call. */
+      if (!EmptyClipboard () ||
+         (h = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, size)) == NULL ||
+         (dst = (unsigned char *) GlobalLock (h)) == NULL)
+       {
+         if (h != NULL) GlobalFree (h);
+         CloseClipboard ();
+         UNGCPRO;
+         return Qnil;
+       }
+      src = XSTRING_DATA (string);
 
-      /* Convert CRLFs to LFs */
-      ret = make_uninit_string (size);
-      dst = XSTRING_DATA (ret);
+      /* Convert LFs to CRLFs */
       do
        {
-         /* copy next line or remaining bytes excluding '\0' */
-         next = memccpy (dst, src, '\r', rawsize);
+         /* copy next line or remaining bytes including '\0' */
+         next = (char*) memccpy (dst, src, '\n', rawsize);
          if (next)
            {
-             /* copied one line ending with '\r' */
+             /* copied one line ending with '\n' */
              int copied = next - dst;
              rawsize -= copied;
              src += copied;
-             if (*src == '\n')
-               dst += copied - 1;              /* overwrite '\r' */
-             else
-               dst += copied;
+             /* insert '\r' before '\n' */
+             next[-1] = '\r';
+             next[0] = '\n';
+             dst = next+1;
            }       
        }
       while (next);
-
+    
       GlobalUnlock (h);
-    }
+  
+      i = (SetClipboardData (CF_TEXT, h) != NULL);
+  
+      CloseClipboard ();
 
-  CloseClipboard ();
+      UNGCPRO;
+      /* #### we are supposed to return a time! */
+      /* return i ? Qt : Qnil; */
+      return Qnil;
+    }
 
-  return ret;
+  return Qnil;
 }
 
 static Lisp_Object
-mswindows_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type)
+mswindows_get_foreign_selection (Lisp_Object selection_symbol,
+                                Lisp_Object target_type)
 {
-  return Fmswindows_get_clipboard ();
-}
+  if (EQ (selection_symbol, QCLIPBOARD))
+    {
+      HANDLE h;
+      unsigned char *src, *dst, *next;
+      Lisp_Object ret = Qnil;
 
-DEFUN ("mswindows-selection-exists-p", Fmswindows_selection_exists_p, 0, 0, 0, /*
-Whether there is an MS-Windows selection.
-*/
-       ())
-{
-  return IsClipboardFormatAvailable (CF_TEXT) ? Qt : Qnil;
-}
+      if (!OpenClipboard (NULL))
+       return Qnil;
 
-DEFUN ("mswindows-delete-selection", Fmswindows_delete_selection, 0, 0, 0, /*
-Remove the current MS-Windows selection from the clipboard.
-*/
-       ())
-{
-  return EmptyClipboard () ? Qt : Qnil;
+      if ((h = GetClipboardData (CF_TEXT)) != NULL &&
+         (src = (unsigned char *) GlobalLock (h)) != NULL)
+       {
+         int i;
+         int size, rawsize;
+         size = rawsize = strlen (src);
+
+         for (i=0; i<rawsize; i++)
+           if (src[i] == '\r' && src[i+1] == '\n')
+             size--;
+
+         /* Convert CRLFs to LFs */
+         ret = make_uninit_string (size);
+         dst = XSTRING_DATA (ret);
+         do
+           {
+             /* copy next line or remaining bytes excluding '\0' */
+             next = (unsigned char *) memccpy (dst, src, '\r', rawsize);
+             if (next)
+               {
+                 /* copied one line ending with '\r' */
+                 int copied = next - dst;
+                 rawsize -= copied;
+                 src += copied;
+                 if (*src == '\n')
+                   dst += copied - 1;          /* overwrite '\r' */
+                 else
+                   dst += copied;
+               }           
+           }
+         while (next);
+
+         GlobalUnlock (h);
+       }
+
+      CloseClipboard ();
+
+      return ret;
+    }
+  else
+    return Qnil;
 }
 
 static void
 mswindows_disown_selection (Lisp_Object selection, Lisp_Object timeval)
 {
-  Fmswindows_delete_selection ();
+  if (EQ (selection, QCLIPBOARD))
+    {
+      BOOL success = OpenClipboard (NULL);
+      if (success)
+       {
+         success = EmptyClipboard ();
+         /* Close it regardless of whether empty worked. */
+         if (!CloseClipboard ())
+           success = FALSE;
+       }
+
+      /* #### return success ? Qt : Qnil; */
+    }
+}
+
+static Lisp_Object
+mswindows_selection_exists_p (Lisp_Object selection)
+{
+  if (EQ (selection, QCLIPBOARD))
+    return IsClipboardFormatAvailable (CF_TEXT) ? Qt : Qnil;
+  else
+    return Qnil;
 }
 
 \f
@@ -197,16 +218,13 @@ console_type_create_select_mswindows (void)
 {
   CONSOLE_HAS_METHOD (mswindows, own_selection);
   CONSOLE_HAS_METHOD (mswindows, disown_selection);
+  CONSOLE_HAS_METHOD (mswindows, selection_exists_p);
   CONSOLE_HAS_METHOD (mswindows, get_foreign_selection);
 }
 
 void
 syms_of_select_mswindows (void)
 {
-  DEFSUBR (Fmswindows_set_clipboard);
-  DEFSUBR (Fmswindows_get_clipboard);
-  DEFSUBR (Fmswindows_selection_exists_p);
-  DEFSUBR (Fmswindows_delete_selection);
 }
 
 void