root/src/w16select.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. identify_winoldap_version
  2. open_clipboard
  3. empty_clipboard
  4. alloc_xfer_buf
  5. free_xfer_buf
  6. set_clipboard_data
  7. get_clipboard_data_size
  8. get_clipboard_data
  9. close_clipboard
  10. clipboard_compact
  11. DEFUN
  12. syms_of_win16select

     1 /* 16-bit Windows Selection processing for emacs on MS-Windows
     2 
     3 Copyright (C) 1996-1997, 2001-2023 Free Software Foundation, Inc.
     4 
     5 Author: Dale P. Smith <dpsm@en.com>
     6 
     7 This file is part of GNU Emacs.
     8 
     9 GNU Emacs is free software: you can redistribute it and/or modify
    10 it under the terms of the GNU General Public License as published by
    11 the Free Software Foundation, either version 3 of the License, or (at
    12 your option) any later version.
    13 
    14 GNU Emacs is distributed in the hope that it will be useful,
    15 but WITHOUT ANY WARRANTY; without even the implied warranty of
    16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    17 GNU General Public License for more details.
    18 
    19 You should have received a copy of the GNU General Public License
    20 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
    21 
    22 /* These functions work by using WinOldAp interface.  WinOldAp
    23    (WINOLDAP.MOD) is a Microsoft Windows extension supporting
    24    "old" (character-mode) application access to Dynamic Data Exchange,
    25    menus, and the Windows clipboard.  */
    26 
    27 /* Adapted to DJGPP by Eli Zaretskii <eliz@gnu.org>  */
    28 
    29 #ifdef MSDOS
    30 
    31 #include <config.h>
    32 #include <dpmi.h>
    33 #include <go32.h>
    34 #include <sys/farptr.h>
    35 #include "lisp.h"
    36 #include "dispextern.h" /* frame.h seems to want this */
    37 #include "frame.h"      /* Need this to get the X window of selected_frame */
    38 #include "blockinput.h"
    39 #include "character.h"
    40 #include "buffer.h"
    41 #include "coding.h"
    42 #include "composite.h"
    43 
    44 /* If ever some function outside this file will need to call any
    45    clipboard-related function, the following prototypes and constants
    46    should be put on a header file.  Right now, nobody else uses them.  */
    47 
    48 #define CF_TEXT      0x01
    49 #define CF_BITMAP    0x02
    50 #define CF_METAFILE  0x03
    51 #define CF_SYLK      0x04
    52 #define CF_DIF       0x05
    53 #define CF_TIFF      0x06
    54 #define CF_OEMTEXT   0x07
    55 #define CF_DIBBITMAP 0x08
    56 #define CF_WINWRITE  0x80
    57 #define CF_DSPTEXT   0x81
    58 #define CF_DSPBITMAP 0x82
    59 
    60 unsigned identify_winoldap_version (void);
    61 unsigned open_clipboard (void);
    62 unsigned empty_clipboard (void);
    63 unsigned set_clipboard_data (unsigned, void *, unsigned, int);
    64 unsigned get_clipboard_data_size (unsigned);
    65 unsigned get_clipboard_data (unsigned, void *, unsigned, int);
    66 unsigned close_clipboard (void);
    67 unsigned clipboard_compact (unsigned);
    68 
    69 /* The segment address and the size of the buffer in low
    70    memory used to move data between us and WinOldAp module.  */
    71 static struct {
    72   unsigned long size;
    73   unsigned short rm_segment;
    74 } clipboard_xfer_buf_info;
    75 
    76 /* The last text we put into the clipboard.  This is used to prevent
    77    passing back our own text from the clipboard, instead of using the
    78    kill ring.  The former is undesirable because the clipboard data
    79    could be MULEtilated by inappropriately chosen
    80    (next-)selection-coding-system.  For this reason, we must store the
    81    text *after* it was encoded/Unix-to-DOS-converted.  */
    82 static unsigned char *last_clipboard_text;
    83 
    84 /* The size of allocated storage for storing the clipboard data.  */
    85 static size_t clipboard_storage_size;
    86 
    87 /* C functions to access the Windows 3.1x clipboard from DOS apps.
    88 
    89    The information was obtained from the Microsoft Knowledge Base,
    90    article Q67675 and can be found at: [broken link  -- SK 2021-09-27]
    91    http://www.microsoft.com/kb/developr/win_dk/q67675.htm  */
    92 
    93 /* See also Ralf Brown's Interrupt List.
    94 
    95    I also seem to remember reading about this in Dr. Dobbs Journal a
    96    while ago, but if you knew my memory...  :-)
    97 
    98    Dale P. Smith <dpsm@en.com> */
    99 
   100 /* Return the WinOldAp support version, or 0x1700 if not supported.  */
   101 unsigned
   102 identify_winoldap_version (void)
   103 {
   104   __dpmi_regs regs;
   105 
   106   /* Calls Int 2Fh/AX=1700h
   107      Return Values   AX == 1700H: Clipboard functions not available
   108                         <> 1700H: AL = Major version number
   109                                   AH = Minor version number */
   110   regs.x.ax = 0x1700;
   111   __dpmi_int (0x2f, &regs);
   112   return regs.x.ax;
   113 }
   114 
   115 /* Open the clipboard, return non-zero if successful.  */
   116 unsigned
   117 open_clipboard (void)
   118 {
   119   __dpmi_regs regs;
   120 
   121   /* Is WINOLDAP supported?  */
   122   /* Kludge alert!!  If WinOldAp is not supported, we return a 0,
   123      which is the same as ``Clipboard already open''.  Currently,
   124      this is taken as an error by all the functions that use
   125      `open_clipboard', but if somebody someday will use that ``open''
   126      clipboard, they will have interesting time debugging it...  */
   127   if (identify_winoldap_version () == 0x1700)
   128     return 0;
   129 
   130   /* Calls Int 2Fh/AX=1701h
   131      Return Values   AX == 0: Clipboard already open
   132                         <> 0: Clipboard opened */
   133   regs.x.ax = 0x1701;
   134   __dpmi_int (0x2f, &regs);
   135   return regs.x.ax;
   136 }
   137 
   138 /* Empty clipboard, return non-zero if successful.  */
   139 unsigned
   140 empty_clipboard (void)
   141 {
   142   __dpmi_regs regs;
   143 
   144   /* Calls Int 2Fh/AX=1702h
   145      Return Values   AX == 0: Error occurred
   146                         <> 0: OK, Clipboard emptied */
   147   regs.x.ax = 0x1702;
   148   __dpmi_int (0x2f, &regs);
   149   return regs.x.ax;
   150 }
   151 
   152 /* Ensure we have a buffer in low memory with enough memory for data
   153    of size WANT_SIZE.  Return the linear address of the buffer.  */
   154 static unsigned long
   155 alloc_xfer_buf (unsigned want_size)
   156 {
   157   __dpmi_regs regs;
   158 
   159   /* If the usual DJGPP transfer buffer is large enough, use that.  */
   160   if (want_size <= _go32_info_block.size_of_transfer_buffer)
   161     return __tb & 0xfffff;
   162 
   163   /* Don't even try to allocate more than 1MB of memory: DOS cannot
   164      possibly handle that (it will overflow the BX register below).  */
   165   if (want_size > 0xfffff)
   166     return 0;
   167 
   168   /* Need size rounded up to the nearest paragraph, and in
   169      paragraph units (1 paragraph = 16 bytes).  */
   170   clipboard_xfer_buf_info.size = (want_size + 15) >> 4;
   171 
   172   /* The NT DPMI host crashes us if we free DOS memory via the
   173      DPMI service.  Work around by calling DOS allocate/free block.  */
   174   regs.h.ah = 0x48;
   175   regs.x.bx = clipboard_xfer_buf_info.size;
   176   __dpmi_int (0x21, &regs);
   177   if (regs.x.flags & 1)
   178     {
   179       clipboard_xfer_buf_info.size = 0;
   180       return 0;
   181     }
   182 
   183   clipboard_xfer_buf_info.rm_segment = regs.x.ax;
   184   return (((int)clipboard_xfer_buf_info.rm_segment) << 4) & 0xfffff;
   185 }
   186 
   187 /* Free our clipboard buffer.  We always free it after use, because
   188    keeping it leaves less free conventional memory for subprocesses.
   189    The clipboard buffer tends to be large in size, because for small
   190    clipboard data sizes we use the DJGPP transfer buffer.  */
   191 static void
   192 free_xfer_buf (void)
   193 {
   194   /* If the size is 0, we used DJGPP transfer buffer, so don't free.  */
   195   if (clipboard_xfer_buf_info.size)
   196     {
   197       __dpmi_regs regs;
   198 
   199       /* The NT DPMI host crashes us if we free DOS memory via
   200          the DPMI service.  Work around by calling DOS free block.  */
   201       regs.h.ah = 0x49;
   202       regs.x.es = clipboard_xfer_buf_info.rm_segment;
   203       __dpmi_int (0x21, &regs);
   204       clipboard_xfer_buf_info.size = 0;
   205     }
   206 }
   207 
   208 /* Copy data into the clipboard, return zero if successful.  */
   209 unsigned
   210 set_clipboard_data (unsigned Format, void *Data, unsigned Size, int Raw)
   211 {
   212   __dpmi_regs regs;
   213   unsigned truelen;
   214   unsigned long xbuf_addr, buf_offset;
   215   unsigned char *dp = Data, *dstart = dp;
   216 
   217   if (Format != CF_OEMTEXT)
   218     return 3;
   219 
   220   /* need to know final size after '\r' chars are inserted (the
   221      standard CF_OEMTEXT clipboard format uses CRLF line endings,
   222      while Emacs uses just LF internally).  */
   223   truelen = Size + 1;           /* +1 for the terminating null */
   224 
   225   if (!Raw)
   226     {
   227       /* avoid using strchr because it recomputes the length every time */
   228       while ((dp = memchr (dp, '\n', Size - (dp - dstart))) != 0)
   229         {
   230           truelen++;
   231           dp++;
   232         }
   233     }
   234 
   235   if (clipboard_compact (truelen) < truelen)
   236     return 1;
   237 
   238   if ((xbuf_addr = alloc_xfer_buf (truelen)) == 0)
   239     return 1;
   240 
   241   /* Move the buffer into the low memory, convert LF into CR-LF if needed.  */
   242   if (Raw)
   243     {
   244       dosmemput (Data, Size, xbuf_addr);
   245 
   246       /* Terminate with a null, otherwise Windows does strange things
   247          when the text size is an integral multiple of 32 bytes. */
   248       _farpokeb (_dos_ds, xbuf_addr + Size, '\0');
   249     }
   250   else
   251     {
   252       dp = Data;
   253       buf_offset = xbuf_addr;
   254       _farsetsel (_dos_ds);
   255       while (Size--)
   256         {
   257           /* Don't allow them to put binary data into the clipboard, since
   258              it will cause yanked data to be truncated at the first null.  */
   259           if (*dp == '\0')
   260             return 2;
   261           if (*dp == '\n')
   262             _farnspokeb (buf_offset++, '\r');
   263           _farnspokeb (buf_offset++, *dp++);
   264         }
   265 
   266       /* Terminate with a null, otherwise Windows does strange things
   267          when the text size is an integral multiple of 32 bytes. */
   268       _farnspokeb (buf_offset, '\0');
   269     }
   270 
   271   /* Stash away the data we are about to put into the clipboard, so we
   272      could later check inside get_clipboard_data whether the clipboard
   273      still holds our data.  */
   274   if (clipboard_storage_size < truelen)
   275     {
   276       clipboard_storage_size = truelen + 100;
   277       last_clipboard_text =
   278         (char *) xrealloc (last_clipboard_text, clipboard_storage_size);
   279     }
   280   if (last_clipboard_text)
   281     dosmemget (xbuf_addr, truelen, last_clipboard_text);
   282 
   283   /* Calls Int 2Fh/AX=1703h with:
   284                      DX = WinOldAp-Supported Clipboard format
   285                      ES:BX = Pointer to data
   286                      SI:CX = Size of data in bytes
   287      Return Values   AX == 0: Error occurred
   288                         <> 0: OK.  Data copied into the Clipboard.  */
   289   regs.x.ax = 0x1703;
   290   regs.x.dx = Format;
   291   regs.x.si = truelen >> 16;
   292   regs.x.cx = truelen & 0xffff;
   293   regs.x.es = xbuf_addr >> 4;
   294   regs.x.bx = xbuf_addr & 15;
   295   __dpmi_int (0x2f, &regs);
   296 
   297   free_xfer_buf ();
   298 
   299   /* If the above failed, invalidate the local copy of the clipboard.  */
   300   if (regs.x.ax == 0)
   301     *last_clipboard_text = '\0';
   302 
   303   /* Zero means success, otherwise (1, 2, or 3) it's an error.  */
   304   return regs.x.ax > 0 ? 0 : 3;
   305 }
   306 
   307 /* Return the size of the clipboard data of format FORMAT.  */
   308 unsigned
   309 get_clipboard_data_size (unsigned Format)
   310 {
   311   __dpmi_regs regs;
   312 
   313   /* Calls Int 2Fh/AX=1704h with:
   314                      DX = WinOldAp-Supported Clipboard format
   315      Return Values   DX:AX == Size of the data in bytes, including any
   316                               headers.
   317                            == 0 If data in this format is not in
   318                            the clipboard.  */
   319   regs.x.ax = 0x1704;
   320   regs.x.dx = Format;
   321   __dpmi_int (0x2f, &regs);
   322   return ( (((unsigned)regs.x.dx) << 16) | regs.x.ax);
   323 }
   324 
   325 /* Get clipboard data, return its length.
   326    Warning: this doesn't check whether DATA has enough space to hold
   327    SIZE bytes.  */
   328 unsigned
   329 get_clipboard_data (unsigned Format, void *Data, unsigned Size, int Raw)
   330 {
   331   __dpmi_regs regs;
   332   unsigned long xbuf_addr;
   333   unsigned char *dp = Data;
   334 
   335   if (Format != CF_OEMTEXT)
   336     return 0;
   337 
   338   if (Size == 0)
   339     return 0;
   340 
   341   if ((xbuf_addr = alloc_xfer_buf (Size)) == 0)
   342     return 0;
   343 
   344   /* Calls Int 2Fh/AX=1705h with:
   345                      DX = WinOldAp-Supported Clipboard format
   346                      ES:BX = Pointer to data buffer to hold data
   347      Return Values   AX == 0: Error occurred (or data in this format is not
   348                               in the clipboard)
   349                         <> 0: OK  */
   350   regs.x.ax = 0x1705;
   351   regs.x.dx = Format;
   352   regs.x.es = xbuf_addr >> 4;
   353   regs.x.bx = xbuf_addr & 15;
   354   __dpmi_int (0x2f, &regs);
   355   if (regs.x.ax != 0)
   356     {
   357       unsigned char null_char = '\0';
   358       unsigned long xbuf_beg = xbuf_addr;
   359 
   360       /* If last_clipboard_text is NULL, we don't want to slow down
   361          the next loop by an additional test.  */
   362       register unsigned char *lcdp =
   363         last_clipboard_text == NULL ? &null_char : last_clipboard_text;
   364 
   365       /* Copy data from low memory, remove CR
   366          characters before LF if needed.  */
   367       _farsetsel (_dos_ds);
   368       while (Size--)
   369         {
   370           register unsigned char c = _farnspeekb (xbuf_addr++);
   371 
   372           if (*lcdp == c)
   373             lcdp++;
   374 
   375           if ((*dp++ = c) == '\r' && !Raw && _farnspeekb (xbuf_addr) == '\n')
   376             {
   377               dp--;
   378               *dp++ = '\n';
   379               xbuf_addr++;
   380               if (*lcdp == '\n')
   381                 lcdp++;
   382             }
   383           /* Windows reportedly rounds up the size of clipboard data
   384              (passed in SIZE) to a multiple of 32, and removes trailing
   385              spaces from each line without updating SIZE.  We therefore
   386              bail out when we see the first null character.  */
   387           else if (c == '\0')
   388             break;
   389         }
   390 
   391       /* If the text in clipboard is identical to what we put there
   392          last time set_clipboard_data was called, pretend there's no
   393          data in the clipboard.  This is so we don't pass our own text
   394          from the clipboard (which might be troublesome if the killed
   395          text includes null characters).  */
   396       if (last_clipboard_text &&
   397           xbuf_addr - xbuf_beg == (long)(lcdp - last_clipboard_text))
   398         dp = (unsigned char *)Data + 1;
   399     }
   400 
   401   free_xfer_buf ();
   402 
   403   return (unsigned) (dp - (unsigned char *)Data - 1);
   404 }
   405 
   406 /* Close clipboard, return non-zero if successful.  */
   407 unsigned
   408 close_clipboard (void)
   409 {
   410   __dpmi_regs regs;
   411 
   412   /* Calls Int 2Fh/AX=1708h
   413      Return Values   AX == 0: Error occurred
   414                         <> 0: OK */
   415   regs.x.ax = 0x1708;
   416   __dpmi_int (0x2f, &regs);
   417   return regs.x.ax;
   418 }
   419 
   420 /* Compact clipboard data so that at least SIZE bytes is available.  */
   421 unsigned
   422 clipboard_compact (unsigned Size)
   423 {
   424   __dpmi_regs regs;
   425 
   426   /* Calls Int 2Fh/AX=1709H with:
   427                      SI:CX = Desired memory size in bytes.
   428      Return Values   DX:AX == Number of bytes of largest block of free memory.
   429                            == 0 if error or no memory  */
   430   regs.x.ax = 0x1709;
   431   regs.x.si = Size >> 16;
   432   regs.x.cx = Size & 0xffff;
   433   __dpmi_int (0x2f, &regs);
   434   return ((unsigned)regs.x.dx << 16) | regs.x.ax;
   435 }
   436 
   437 static char no_mem_msg[] =
   438   "(Not enough DOS memory to put saved text into clipboard.)";
   439 static char binary_msg[] =
   440   "(Binary characters in saved text; clipboard data not set.)";
   441 static char system_error_msg[] =
   442   "(Clipboard interface failure; clipboard data not set.)";
   443 
   444 DEFUN ("w16-set-clipboard-data", Fw16_set_clipboard_data, Sw16_set_clipboard_data, 1, 2, 0,
   445        doc: /* This sets the clipboard data to the given text.  */)
   446   (Lisp_Object string, Lisp_Object frame)
   447 {
   448   unsigned ok = 1, put_status = 0;
   449   int nbytes, no_crlf_conversion;
   450   unsigned char *src, *dst = NULL;
   451 
   452   CHECK_STRING (string);
   453 
   454   if (!FRAME_MSDOS_P (decode_live_frame (frame)))
   455     goto done;
   456 
   457   block_input ();
   458 
   459   if (!open_clipboard ())
   460     goto error;
   461 
   462   nbytes = SBYTES (string);
   463   src = SDATA (string);
   464 
   465   /* Do we need to encode this text?  */
   466   for (dst = src; dst < src + nbytes; dst++)
   467     {
   468       if (*dst == '\0' || *dst >= 0x80)
   469         break;
   470     }
   471   if (dst >= src + nbytes)
   472     {
   473       /* No multibyte characters in text.  We need not encode it, but we
   474          will have to convert it to DOS CR-LF style.  */
   475       no_crlf_conversion = 0;
   476       Vlast_coding_system_used = Qraw_text;
   477       dst = NULL;       /* so we don't try to free a random pointer */
   478     }
   479   else
   480     {
   481       /* We must encode contents of STRING according to what
   482          clipboard-coding-system specifies.  */
   483       struct coding_system coding;
   484       Lisp_Object coding_system =
   485         NILP (Vnext_selection_coding_system) ?
   486         Vselection_coding_system : Vnext_selection_coding_system;
   487 
   488       setup_coding_system (Fcheck_coding_system (coding_system), &coding);
   489       coding.dst_bytes = nbytes * 4;
   490       coding.destination = xmalloc (coding.dst_bytes);
   491       Vnext_selection_coding_system = Qnil;
   492       coding.mode |= CODING_MODE_LAST_BLOCK;
   493       dst = coding.destination;
   494       encode_coding_object (&coding, string, 0, 0,
   495                             SCHARS (string), nbytes, Qnil);
   496       no_crlf_conversion = 1;
   497       nbytes = coding.produced;
   498       Vlast_coding_system_used = CODING_ID_NAME (coding.id);
   499       src = dst;
   500     }
   501 
   502   ok = empty_clipboard ()
   503     && ((put_status
   504          = set_clipboard_data (CF_OEMTEXT, src, nbytes, no_crlf_conversion))
   505         == 0);
   506 
   507   if (!no_crlf_conversion)
   508   close_clipboard ();
   509 
   510   if (ok) goto unblock;
   511 
   512  error:
   513 
   514   ok = 0;
   515 
   516  unblock:
   517   xfree (dst);
   518   unblock_input ();
   519 
   520   /* Notify user if the text is too large to fit into DOS memory.
   521      (This will happen somewhere after 600K bytes (470K in DJGPP v1.x),
   522      depending on user system configuration.)  If we just silently
   523      fail the function, people might wonder why their text sometimes
   524      doesn't make it to the clipboard.  */
   525   if (put_status)
   526     {
   527       switch (put_status)
   528         {
   529           case 1:
   530             message3 (make_unibyte_string (no_mem_msg, sizeof (no_mem_msg) - 1));
   531             break;
   532           case 2:
   533             message3 (make_unibyte_string (binary_msg, sizeof (binary_msg) - 1));
   534             break;
   535           case 3:
   536             message3 (make_unibyte_string (system_error_msg, sizeof (system_error_msg) - 1));
   537             break;
   538         }
   539       sit_for (make_fixnum (2), 0, 2);
   540     }
   541 
   542  done:
   543 
   544   return (ok && put_status == 0 ? string : Qnil);
   545 }
   546 
   547 DEFUN ("w16-get-clipboard-data", Fw16_get_clipboard_data, Sw16_get_clipboard_data, 0, 1, 0,
   548        doc: /* This gets the clipboard data in text format.  */)
   549   (Lisp_Object frame)
   550 {
   551   unsigned data_size, truelen;
   552   unsigned char *htext = NULL;
   553   Lisp_Object ret = Qnil;
   554   int require_decoding = 0;
   555 
   556   if (!FRAME_MSDOS_P (decode_live_frame (frame)))
   557     goto done;
   558 
   559   block_input ();
   560 
   561   if (!open_clipboard ())
   562     goto unblock;
   563 
   564   if ((data_size = get_clipboard_data_size (CF_OEMTEXT)) == 0 ||
   565       (htext = xmalloc (data_size)) == 0)
   566     goto closeclip;
   567 
   568   /* need to know final size after '\r' chars are removed because
   569      we can't change the string size manually, and doing an extra
   570      copy is silly */
   571   if ((truelen = get_clipboard_data (CF_OEMTEXT, htext, data_size, 0)) == 0)
   572     goto closeclip;
   573 
   574   /* Do we need to decode it?  */
   575   {
   576     /* If the clipboard data contains any 8-bit Latin-1 code, we
   577        need to decode it.  */
   578     int i;
   579 
   580     for (i = 0; i < truelen; i++)
   581       {
   582         if (htext[i] >= 0x80)
   583           {
   584             require_decoding = 1;
   585             break;
   586           }
   587       }
   588   }
   589   if (require_decoding)
   590     {
   591       struct coding_system coding;
   592       Lisp_Object coding_system = Vnext_selection_coding_system;
   593 
   594       truelen = get_clipboard_data (CF_OEMTEXT, htext, data_size, 1);
   595       if (NILP (coding_system))
   596         coding_system = Vselection_coding_system;
   597       setup_coding_system (Fcheck_coding_system (coding_system), &coding);
   598       coding.source = htext;
   599       coding.mode |= CODING_MODE_LAST_BLOCK;
   600       /* We explicitly disable composition handling because selection
   601          data should not contain any composition sequence.  */
   602       coding.common_flags &= ~CODING_ANNOTATION_MASK;
   603       decode_coding_object (&coding, Qnil, 0, 0, truelen, truelen, Qt);
   604       ret = coding.dst_object;
   605       Vlast_coding_system_used = CODING_ID_NAME (coding.id);
   606     }
   607   else
   608     {
   609       ret = make_unibyte_string ((char *) htext, truelen);
   610       Vlast_coding_system_used = Qraw_text;
   611     }
   612 
   613   xfree (htext);
   614   Vnext_selection_coding_system = Qnil;
   615 
   616  closeclip:
   617   close_clipboard ();
   618 
   619  unblock:
   620   unblock_input ();
   621 
   622  done:
   623 
   624   return (ret);
   625 }
   626 
   627 /* Support checking for a clipboard selection.  */
   628 
   629 DEFUN ("w16-selection-exists-p", Fw16_selection_exists_p, Sw16_selection_exists_p,
   630        0, 2, 0,
   631        doc: /* Whether there is an owner for the given X selection.
   632 SELECTION should be the name of the selection in question, typically
   633 one of the symbols `PRIMARY', `SECONDARY', or `CLIPBOARD'.  (X expects
   634 these literal upper-case names.)  The symbol nil is the same as
   635 `PRIMARY', and t is the same as `SECONDARY'.
   636 
   637 TERMINAL should be a terminal object or a frame specifying the X
   638 server to query.  If omitted or nil, that stands for the selected
   639 frame's display, or the first available X display.  */)
   640   (Lisp_Object selection, Lisp_Object terminal)
   641 {
   642   CHECK_SYMBOL (selection);
   643 
   644   /* Return nil for SECONDARY selection.  For PRIMARY (or nil)
   645      selection, check if there is some text on the kill-ring;
   646      for CLIPBOARD, check if the clipboard currently has valid
   647      text format contents.
   648 
   649      The test for killed text on the kill-ring emulates the Emacs
   650      behavior on X, where killed text is also put into X selection
   651      by the X interface code.  (On MSDOS, killed text is only put
   652      into the clipboard if we run under Windows, so we cannot check
   653      the clipboard alone.)  */
   654   if ((NILP (selection) || EQ (selection, QPRIMARY))
   655       && ! NILP (Fsymbol_value (Fintern_soft (build_string ("kill-ring"),
   656                                               Qnil))))
   657     return Qt;
   658 
   659   if (EQ (selection, QCLIPBOARD))
   660     {
   661       Lisp_Object val = Qnil;
   662 
   663       if (open_clipboard ())
   664         {
   665           if (get_clipboard_data_size (CF_OEMTEXT))
   666             val = Qt;
   667           close_clipboard ();
   668         }
   669       return val;
   670     }
   671   return Qnil;
   672 }
   673 
   674 void
   675 syms_of_win16select (void)
   676 {
   677   defsubr (&Sw16_set_clipboard_data);
   678   defsubr (&Sw16_get_clipboard_data);
   679   defsubr (&Sw16_selection_exists_p);
   680 
   681   DEFVAR_LISP ("selection-coding-system", Vselection_coding_system,
   682                doc: /* SKIP: real doc in select.el.  */);
   683   Vselection_coding_system = intern ("iso-latin-1-dos");
   684 
   685   DEFVAR_LISP ("next-selection-coding-system", Vnext_selection_coding_system,
   686                doc: /* SKIP: real doc in select.el.  */);
   687   Vnext_selection_coding_system = Qnil;
   688 
   689   DEFSYM (QCLIPBOARD, "CLIPBOARD");
   690 }
   691 
   692 #endif /* MSDOS */

/* [<][>][^][v][top][bottom][index][help] */