home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
pcmagazi
/
1992
/
15
/
winclip.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-25
|
5KB
|
258 lines
/* WINCLIP.C -- DOS access to Windows Clipboard (Enhanced mode) */
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <signal.h>
#include <dos.h>
#include "winclip.h"
int do_convert = 1;
static int winoldap = 0;
static int clip_open = 0;
static int clip_init(void);
/* higher-level functions */
int WindowsClipboard(void)
{
return (IdentifyWinOldApVersion() != 0);
}
/* NOTE: len includes NULL-termination byte, which is required */
int PutClipStrLen(char *s, unsigned len)
{
char *buf;
if (! winoldap)
if (! clip_init())
return 0;
if (do_convert) /* change all ^M^J to ^J */
{
char *s2;
unsigned len2;
if (! (buf = calloc(len+1, 1)))
return 0; /* insufficient memory */
for (s2=buf, len2=len; len2--; s2++, s++)
{
if ((s[0] == 0x0d) && (s[1] == 0x0a))
{
s++;
len--; /* remove 0D */
}
*s2 = *s;
}
*s2 = '\0';
}
else
buf=s;
if (! OpenClipboard())
return 0;
if (! EmptyClipboard())
{
CloseClipboard();
return 0; /* couldn't empty */
}
if (CompactClipboard(len) < len)
{
CloseClipboard();
return 0; /* couldn't compact */
}
if (! SetClipboardData(CF_TEXT, buf, len))
{
CloseClipboard();
return 0; /* couldn't set */
}
CloseClipboard();
if (do_convert)
free(buf);
Yield();
return 1;
}
int PutClipString(char *str)
{
return PutClipStrLen(str, strlen(str)+1);
}
char *GetClipString(void)
{
unsigned long len;
char *s;
if (! winoldap)
if (! clip_init())
return (char *) 0;
if (! OpenClipboard())
return (char *) 0;
/* MUST do OpenClipboard BEFORE GetClipboardDataSize */
if ((len = GetClipboardDataSize(CF_TEXT)) == 0)
{
CloseClipboard();
return (char *) 0; /* nothing there */
}
if (len > (0xFFFFU - 16))
{
CloseClipboard();
return (char *) 0; /* too big */
}
if ((s = (char *) calloc((unsigned) len+1, 1)) == NULL)
{
CloseClipboard();
return (char *) 0; /* insufficient memory */
}
if (! GetClipboardData(CF_TEXT, s))
{
CloseClipboard();
return (char *) 0; /* couldn't get it */
}
CloseClipboard();
Yield();
return s;
}
void FreeClipString(char *s)
{
free(s);
}
/**********************************************************************/
/* lower-level functions */
void sigint_handler(int sig)
{
if (clip_open != 0)
CloseClipboard();
exit(1);
}
void exit_func(void)
{
if (clip_open != 0)
CloseClipboard();
}
static int clip_init(void)
{
if (! (winoldap = IdentifyWinOldApVersion()))
return 0;
atexit(exit_func);
signal(SIGINT, sigint_handler);
return 1;
}
unsigned long CompactClipboard(unsigned long len)
{
_asm push si
_asm mov ax, 1709h
_asm mov si, word ptr len+2
_asm mov cx, word ptr len
_asm int 2fh
_asm pop si
/* return value in DX:AX (size) */
}
unsigned CloseClipboard(void)
{
unsigned retval;
_asm mov ax, 1708h
_asm int 2fh
_asm mov retval, ax
if (retval) clip_open--;
Yield(); /* seems like a good place to put it */
return retval;
}
unsigned EmptyClipboard(void)
{
_asm mov ax, 1702h
_asm int 2fh
/* return value in AX (0 if failure) */
}
unsigned char far *GetClipboardData(CF_FORMAT format,
unsigned char far *buf)
{
unsigned retval;
_asm mov ax, 1705h
_asm mov dx, format
_asm les bx, buf
_asm int 2fh
_asm mov retval, ax
return retval? buf : (unsigned char far *) 0;
}
unsigned long GetClipboardDataSize(CF_FORMAT format)
{
_asm mov ax, 1704h
_asm mov dx, format
_asm int 2fh
/* return value in DX:AX (size) */
}
unsigned GetDeviceCaps(unsigned index)
{
_asm mov ax, 170Ah
_asm mov dx, index
_asm int 2fh
/* return value in AX (device capability) */
}
unsigned IdentifyWinOldApVersion(void)
{
unsigned vers;
_asm mov ax, 1700h
_asm int 2fh
_asm mov vers, ax
/* if AX still 1700h, then WINOLDAP not present */
return (vers == 0x1700) ? 0 : vers;
}
unsigned OpenClipboard(void)
{
unsigned retval;
_asm mov ax, 1701h
_asm int 2fh
_asm mov retval, ax
if (retval) clip_open++;
return retval;
}
unsigned SetClipboardData(CF_FORMAT format, unsigned char far *buf,
unsigned long len)
{
_asm push si
_asm mov ax, 1703h
_asm mov dx, format
_asm les bx, buf
_asm mov si, word ptr len+2
_asm mov cx, word ptr len
_asm int 2fh
_asm pop si
/* return value in AX (0 if failure) */
}
/* Problem with Yield: as soon as DOS box makes even one Yield,
it barely runs in the background anymore (especially in 3.1) */
void Yield(void)
{
#if 1
_asm int 28h
_asm int 28h
_asm int 28h
#else
_asm mov ax, 1680h
_asm int 2fh
#endif
}