home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast.iso / pcmag / vol11n15.zip / WINCLIP.C < prev    next >
C/C++ Source or Header  |  1992-05-25  |  5KB  |  258 lines

  1. /* WINCLIP.C -- DOS access to Windows Clipboard (Enhanced mode) */
  2.  
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <malloc.h>
  6. #include <signal.h>
  7. #include <dos.h>
  8. #include "winclip.h"
  9.  
  10. int do_convert = 1;
  11.  
  12. static int winoldap = 0;
  13. static int clip_open = 0;
  14.  
  15. static int clip_init(void);
  16.  
  17. /* higher-level functions */
  18.  
  19. int WindowsClipboard(void)
  20. {
  21.     return (IdentifyWinOldApVersion() != 0);
  22. }
  23.     
  24. /* NOTE: len includes NULL-termination byte, which is required */
  25. int PutClipStrLen(char *s, unsigned len)
  26. {
  27.     char *buf;
  28.     
  29.     if (! winoldap)
  30.         if (! clip_init())
  31.             return 0;
  32.         
  33.     if (do_convert)     /* change all ^M^J to ^J */
  34.     {
  35.         char *s2;
  36.         unsigned len2;
  37.         
  38.         if (! (buf = calloc(len+1, 1)))
  39.             return 0;   /* insufficient memory */
  40.  
  41.         for (s2=buf, len2=len; len2--; s2++, s++)
  42.         {
  43.             if ((s[0] == 0x0d) && (s[1] == 0x0a))
  44.             {
  45.                 s++;
  46.                 len--;  /* remove 0D */
  47.             }
  48.             *s2 = *s;
  49.         }
  50.         *s2 = '\0';
  51.     }
  52.     else
  53.         buf=s;
  54.     
  55.     if (! OpenClipboard())
  56.         return 0;
  57.     if (! EmptyClipboard())
  58.     {
  59.         CloseClipboard();
  60.         return 0;               /* couldn't empty */
  61.     }
  62.     if (CompactClipboard(len) < len)
  63.     {
  64.         CloseClipboard();
  65.         return 0;               /* couldn't compact */
  66.     }
  67.     if (! SetClipboardData(CF_TEXT, buf, len))
  68.     {
  69.         CloseClipboard();
  70.         return 0;               /* couldn't set */
  71.     }
  72.     CloseClipboard();
  73.     if (do_convert)
  74.         free(buf);
  75.     Yield();
  76.     return 1;
  77. }
  78.  
  79. int PutClipString(char *str)
  80. {
  81.     return PutClipStrLen(str, strlen(str)+1);
  82. }
  83.  
  84. char *GetClipString(void)
  85. {
  86.     unsigned long len;
  87.     char *s;
  88.     
  89.     if (! winoldap)
  90.         if (! clip_init())
  91.             return (char *) 0;
  92.  
  93.     if (! OpenClipboard())
  94.         return (char *) 0;
  95.     /* MUST do OpenClipboard BEFORE GetClipboardDataSize */
  96.     if ((len = GetClipboardDataSize(CF_TEXT)) == 0)
  97.     {
  98.         CloseClipboard();
  99.         return (char *) 0;      /* nothing there */
  100.     }
  101.     if (len > (0xFFFFU - 16))
  102.     {
  103.         CloseClipboard();
  104.         return (char *) 0;      /* too big */
  105.     }
  106.     if ((s = (char *) calloc((unsigned) len+1, 1)) == NULL)
  107.     {
  108.         CloseClipboard();
  109.         return (char *) 0;      /* insufficient memory */
  110.     }
  111.     if (! GetClipboardData(CF_TEXT, s))
  112.     {
  113.         CloseClipboard();
  114.         return (char *) 0;      /* couldn't get it */
  115.     }
  116.     CloseClipboard();
  117.     Yield();
  118.     return s;
  119. }
  120.  
  121. void FreeClipString(char *s)
  122. {
  123.     free(s);
  124. }
  125.  
  126. /**********************************************************************/
  127.  
  128. /* lower-level functions */
  129.  
  130. void sigint_handler(int sig)
  131. {
  132.     if (clip_open != 0)
  133.         CloseClipboard();
  134.     exit(1);
  135. }
  136.  
  137. void exit_func(void)
  138. {
  139.     if (clip_open != 0)
  140.         CloseClipboard();
  141. }
  142.  
  143. static int clip_init(void)
  144. {
  145.     if (! (winoldap = IdentifyWinOldApVersion()))
  146.         return 0;
  147.     
  148.     atexit(exit_func);
  149.     signal(SIGINT, sigint_handler);
  150.     return 1;
  151. }
  152.  
  153. unsigned long CompactClipboard(unsigned long len)
  154. {
  155.     _asm push si
  156.     _asm mov ax, 1709h
  157.     _asm mov si, word ptr len+2
  158.     _asm mov cx, word ptr len
  159.     _asm int 2fh
  160.     _asm pop si
  161.     /* return value in DX:AX (size) */
  162. }
  163.  
  164. unsigned CloseClipboard(void)
  165. {
  166.     unsigned retval;
  167.     _asm mov ax, 1708h
  168.     _asm int 2fh
  169.     _asm mov retval, ax
  170.     if (retval) clip_open--;
  171.     Yield();    /* seems like a good place to put it */
  172.     return retval;
  173. }
  174.  
  175. unsigned EmptyClipboard(void)
  176. {
  177.     _asm mov ax, 1702h
  178.     _asm int 2fh
  179.     /* return value in AX (0 if failure) */
  180. }
  181.  
  182. unsigned char far *GetClipboardData(CF_FORMAT format, 
  183.     unsigned char far *buf)
  184. {
  185.     unsigned retval;
  186.     _asm mov ax, 1705h
  187.     _asm mov dx, format
  188.     _asm les bx, buf
  189.     _asm int 2fh
  190.     _asm mov retval, ax
  191.     return retval? buf : (unsigned char far *) 0;
  192. }
  193.  
  194. unsigned long GetClipboardDataSize(CF_FORMAT format)
  195. {
  196.     _asm mov ax, 1704h
  197.     _asm mov dx, format
  198.     _asm int 2fh
  199.     /* return value in DX:AX (size) */
  200. }
  201.  
  202. unsigned GetDeviceCaps(unsigned index)
  203. {
  204.     _asm mov ax, 170Ah
  205.     _asm mov dx, index
  206.     _asm int 2fh
  207.     /* return value in AX (device capability) */
  208. }
  209.  
  210. unsigned IdentifyWinOldApVersion(void)
  211. {
  212.     unsigned vers;
  213.     _asm mov ax, 1700h
  214.     _asm int 2fh
  215.     _asm mov vers, ax
  216.     /* if AX still 1700h, then WINOLDAP not present */
  217.     return (vers == 0x1700) ? 0 : vers;
  218. }
  219.  
  220. unsigned OpenClipboard(void)
  221. {
  222.     unsigned retval;
  223.     _asm mov ax, 1701h
  224.     _asm int 2fh
  225.     _asm mov retval, ax
  226.     if (retval) clip_open++;
  227.     return retval;
  228. }
  229.  
  230. unsigned SetClipboardData(CF_FORMAT format, unsigned char far *buf, 
  231.     unsigned long len)
  232. {
  233.     _asm push si
  234.     _asm mov ax, 1703h
  235.     _asm mov dx, format
  236.     _asm les bx, buf
  237.     _asm mov si, word ptr len+2
  238.     _asm mov cx, word ptr len
  239.     _asm int 2fh
  240.     _asm pop si
  241.     /* return value in AX (0 if failure) */
  242. }
  243.  
  244. /* Problem with Yield:  as soon as DOS box makes even one Yield,
  245.    it barely runs in the background anymore (especially in 3.1) */
  246. void Yield(void)
  247. {
  248. #if 1
  249.     _asm int 28h
  250.     _asm int 28h
  251.     _asm int 28h
  252. #else
  253.     _asm mov ax, 1680h
  254.     _asm int 2fh
  255. #endif        
  256. }
  257.  
  258.