+/* A list of handles that we must release. Not accessible from Lisp. */
+static Lisp_Object Vhandle_alist;
+
+/* Test if this is an X symbol that we understand */
+static int
+x_sym_p (Lisp_Object value)
+{
+ if (NILP (value) || INTP (value))
+ return 0;
+
+ /* Check for some of the X symbols */
+ if (EQ (value, QSTRING)) return 1;
+ if (EQ (value, QTEXT)) return 1;
+ if (EQ (value, QCOMPOUND_TEXT)) return 1;
+
+ return 0;
+}
+
+/* This converts a Lisp symbol to an MS-Windows clipboard format.
+ We have symbols for all predefined clipboard formats, but that
+ doesn't mean we support them all ;-)
+ The name of this function is actually a lie - it also knows about
+ integers and strings... */
+static UINT
+symbol_to_ms_cf (Lisp_Object value)
+{
+ /* If it's NIL, we're in trouble. */
+ if (NILP (value)) return 0;
+
+ /* If it's an integer, assume it's a format ID */
+ if (INTP (value)) return (UINT) (XINT (value));
+
+ /* If it's a string, register the format(!) */
+ if (STRINGP (value))
+ return RegisterClipboardFormat (XSTRING_DATA (value));
+
+ /* Check for Windows clipboard format symbols */
+ if (EQ (value, QCF_TEXT)) return CF_TEXT;
+ if (EQ (value, QCF_BITMAP)) return CF_BITMAP;
+ if (EQ (value, QCF_METAFILEPICT)) return CF_METAFILEPICT;
+ if (EQ (value, QCF_SYLK)) return CF_SYLK;
+ if (EQ (value, QCF_DIF)) return CF_DIF;
+ if (EQ (value, QCF_TIFF)) return CF_TIFF;
+ if (EQ (value, QCF_OEMTEXT)) return CF_OEMTEXT;
+ if (EQ (value, QCF_DIB)) return CF_DIB;
+#ifdef CF_DIBV5
+ if (EQ (value, QCF_DIBV5)) return CF_DIBV5;
+#endif
+ if (EQ (value, QCF_PALETTE)) return CF_PALETTE;
+ if (EQ (value, QCF_PENDATA)) return CF_PENDATA;
+ if (EQ (value, QCF_RIFF)) return CF_RIFF;
+ if (EQ (value, QCF_WAVE)) return CF_WAVE;
+ if (EQ (value, QCF_UNICODETEXT)) return CF_UNICODETEXT;
+ if (EQ (value, QCF_ENHMETAFILE)) return CF_ENHMETAFILE;
+ if (EQ (value, QCF_HDROP)) return CF_HDROP;
+ if (EQ (value, QCF_LOCALE)) return CF_LOCALE;
+ if (EQ (value, QCF_OWNERDISPLAY)) return CF_OWNERDISPLAY;
+ if (EQ (value, QCF_DSPTEXT)) return CF_DSPTEXT;
+ if (EQ (value, QCF_DSPBITMAP)) return CF_DSPBITMAP;
+ if (EQ (value, QCF_DSPMETAFILEPICT)) return CF_DSPMETAFILEPICT;
+ if (EQ (value, QCF_DSPENHMETAFILE)) return CF_DSPENHMETAFILE;
+
+ return 0;
+}
+
+/* This converts an MS-Windows clipboard format to its corresponding
+ Lisp symbol, or a Lisp integer otherwise. */
+static Lisp_Object
+ms_cf_to_symbol (UINT format)
+{
+ switch (format)
+ {
+ case CF_TEXT: return QCF_TEXT;
+ case CF_BITMAP: return QCF_BITMAP;
+ case CF_METAFILEPICT: return QCF_METAFILEPICT;
+ case CF_SYLK: return QCF_SYLK;
+ case CF_DIF: return QCF_DIF;
+ case CF_TIFF: return QCF_TIFF;
+ case CF_OEMTEXT: return QCF_OEMTEXT;
+ case CF_DIB: return QCF_DIB;
+#ifdef CF_DIBV5
+ case CF_DIBV5: return QCF_DIBV5;
+#endif
+ case CF_PALETTE: return QCF_PALETTE;
+ case CF_PENDATA: return QCF_PENDATA;
+ case CF_RIFF: return QCF_RIFF;
+ case CF_WAVE: return QCF_WAVE;
+ case CF_UNICODETEXT: return QCF_UNICODETEXT;
+ case CF_ENHMETAFILE: return QCF_ENHMETAFILE;
+ case CF_HDROP: return QCF_HDROP;
+ case CF_LOCALE: return QCF_LOCALE;
+ case CF_OWNERDISPLAY: return QCF_OWNERDISPLAY;
+ case CF_DSPTEXT: return QCF_DSPTEXT;
+ case CF_DSPBITMAP: return QCF_DSPBITMAP;
+ case CF_DSPMETAFILEPICT: return QCF_DSPMETAFILEPICT;
+ case CF_DSPENHMETAFILE: return QCF_DSPENHMETAFILE;
+ default: return make_int ((int) format);
+ }
+}
+
+/* Test if the specified clipboard format is auto-released by the OS. If
+ not, we must remember the handle on Vhandle_alist, and free it if
+ the clipboard is emptied or if we set data with the same format. */
+static int
+cf_is_autofreed (UINT format)
+{
+ switch (format)
+ {
+ /* This list comes from the SDK documentation */
+ case CF_DSPENHMETAFILE:
+ case CF_DSPMETAFILEPICT:
+ case CF_ENHMETAFILE:
+ case CF_METAFILEPICT:
+ case CF_BITMAP:
+ case CF_DSPBITMAP:
+ case CF_PALETTE:
+ case CF_DIB:
+#ifdef CF_DIBV5
+ case CF_DIBV5:
+#endif
+ case CF_DSPTEXT:
+ case CF_OEMTEXT:
+ case CF_TEXT:
+ case CF_UNICODETEXT:
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
+
+/* Do protocol to assert ourself as a selection owner.
+
+ Under mswindows, we:
+
+ * Only set the clipboard if (eq selection-name 'CLIPBOARD)
+
+ * Check if an X atom name has been passed. If so, convert to CF_TEXT
+ (or CF_UNICODETEXT) remembering to perform LF -> CR-LF conversion.
+
+ * Otherwise assume the data is formatted appropriately for the data type
+ that was passed.