X-Git-Url: http://git.chise.org/gitweb/?p=chise%2Fxemacs-chise.git.1;a=blobdiff_plain;f=src%2Fselect-msw.c;h=67b4c89e86548cd6e48a83d1b1b4b22075926a3f;hp=f72a46cf4610a1f2db118099a61b8331a2d783f6;hb=14ac73276fa152e8f0b74602792afc0b9c3236c9;hpb=3890a2e3064a7f562107c58e59d928284ec04741 diff --git a/src/select-msw.c b/src/select-msw.c index f72a46c..67b4c89 100644 --- a/src/select-msw.c +++ b/src/select-msw.c @@ -24,185 +24,550 @@ Boston, MA 02111-1307, USA. */ Written by Kevin Gallo for FSF Emacs. Rewritten for mswindows by Jonathan Harris, December 1997 for 21.0. - */ - + Hacked by Alastair Houghton, July 2000 for enhanced clipboard support. +*/ #include #include "lisp.h" #include "frame.h" #include "select.h" +#include "opaque.h" +#include "file-coding.h" +#include "buffer.h" #include "console-msw.h" -DEFUN ("mswindows-set-clipboard", Fmswindows_set_clipboard, 1, 1, 0, /* -Copy STRING to the mswindows clipboard. +/* 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. + + Then set the clipboard as necessary. */ - (string)) +static Lisp_Object +mswindows_own_selection (Lisp_Object selection_name, + Lisp_Object selection_value, + Lisp_Object how_to_add, + Lisp_Object selection_type, + int owned_p /* Not used */) { - int rawsize, size, i; - unsigned char *src, *dst, *next; - HGLOBAL h = NULL; - struct frame *f = NULL; + HGLOBAL hValue = NULL; + UINT cfType; + int is_X_type = FALSE; + Lisp_Object cfObject; + Lisp_Object data = Qnil; + int size; + void *src, *dst; + struct frame *f = NULL; + + /* Only continue if we're trying to set the clipboard - mswindows doesn't + use the same selection model as X */ + if (!EQ (selection_name, QCLIPBOARD)) + return Qnil; + + /* If this is one of the X-style atom name symbols, or NIL, convert it + as appropriate */ + if (NILP (selection_type) || x_sym_p (selection_type)) + { + /* Should COMPOUND_TEXT map to CF_UNICODETEXT? */ + cfType = CF_TEXT; + cfObject = QCF_TEXT; + is_X_type = TRUE; + } + else + { + cfType = symbol_to_ms_cf (selection_type); + + /* Only continue if we can figure out a clipboard type */ + if (!cfType) + return Qnil; + + cfObject = selection_type; + } + + /* Convert things appropriately */ + data = select_convert_out (selection_name, + cfObject, + selection_value); - CHECK_STRING (string); + if (NILP (data)) + return Qnil; + + if (CONSP (data)) + { + if (!EQ (XCAR (data), cfObject)) + cfType = symbol_to_ms_cf (XCAR (data)); - /* 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