|
<!-- Creator : groff version 1.22.4 -->
|
|
<!-- CreationDate: Mon Jan 13 08:04:04 2020 -->
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
|
"http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<meta name="generator" content="groff -Thtml, see www.gnu.org">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
|
<meta name="Content-Style" content="text/css">
|
|
<style type="text/css">
|
|
p { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
|
pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
|
table { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
|
h1 { text-align: center }
|
|
</style>
|
|
<title>tiny_clipnwrite</title>
|
|
|
|
</head>
|
|
<body>
|
|
|
|
<h1 align="center">tiny_clipnwrite</h1>
|
|
|
|
<a href="#NAME">NAME</a><br>
|
|
<a href="#SYNOPSIS">SYNOPSIS</a><br>
|
|
<a href="#DESCRIPTION">DESCRIPTION</a><br>
|
|
<a href="#RETURN VALUE">RETURN VALUE</a><br>
|
|
<a href="#ERRORS">ERRORS</a><br>
|
|
<a href="#EXAMPLES">EXAMPLES</a><br>
|
|
<a href="#NOTES">NOTES</a><br>
|
|
<a href="#SEE ALSO">SEE ALSO</a><br>
|
|
<a href="#AUTHOR">AUTHOR</a><br>
|
|
|
|
<hr>
|
|
|
|
|
|
<h2>NAME
|
|
<a name="NAME"></a>
|
|
</h2>
|
|
|
|
|
|
|
|
<p style="margin-left:11%; margin-top: 1em">tiny_clipwrite,
|
|
tiny_clipnwrite - Write to the OS clipboard</p>
|
|
|
|
<h2>SYNOPSIS
|
|
<a name="SYNOPSIS"></a>
|
|
</h2>
|
|
|
|
|
|
<p style="margin-left:11%; margin-top: 1em"><b>#include
|
|
<tiynclipboard.h></b></p>
|
|
|
|
<p style="margin-left:11%; margin-top: 1em"><b>int
|
|
tiny_clipnwrite</b>(<b>const char*</b> <i>text</i>,
|
|
<b>int</b> <i>len</i>); <b><br>
|
|
int tiny_clipwrite</b>(<b>const char*</b> <i>text</i>);</p>
|
|
|
|
<h2>DESCRIPTION
|
|
<a name="DESCRIPTION"></a>
|
|
</h2>
|
|
|
|
|
|
<p style="margin-left:11%; margin-top: 1em">The
|
|
<b>tiny_clipnwrite()</b> function reads <i>len</i> bytes
|
|
from the string buffer pointed to by <i>text</i> and writes
|
|
them to the underlying graphics stack’s clipboard.
|
|
There are no size checks performed while reading from the
|
|
buffer, so that this function allows you to embed <b>NUL</b>
|
|
bytes into the clipboard. It is your responsibility to set
|
|
the <i>len</i> argument accordingly. <i>text</i> is expected
|
|
to be encoded in UTF-8 regardless of the current
|
|
locale’s encoding.</p>
|
|
|
|
<p style="margin-left:11%; margin-top: 1em">The
|
|
<b>tiny_clipwrite()</b> function behaves like the
|
|
<b>tiny_clipnwrite()</b> function, except that it determines
|
|
the length of the string to write to the clipboard by
|
|
utilising the <b>strlen(3)</b> function on its <i>text</i>
|
|
argument. It is thus not possible to copy a string
|
|
containing <b>NUL</b> bytes into the clipboard using this
|
|
function; use <b>tiny_clipnwrite()</b> if you need to do
|
|
this.</p>
|
|
|
|
<h2>RETURN VALUE
|
|
<a name="RETURN VALUE"></a>
|
|
</h2>
|
|
|
|
|
|
<p style="margin-left:11%; margin-top: 1em">The
|
|
<b>tiny_clipnwrite()</b> and <b>tiny_clipwrite()</b>
|
|
functions return 0 if the data was written successfully into
|
|
the operating system’s clipboard. Otherwise they
|
|
return -1 and set <i>errno</i> to indicate the error.</p>
|
|
|
|
<h2>ERRORS
|
|
<a name="ERRORS"></a>
|
|
</h2>
|
|
|
|
|
|
<p style="margin-left:11%; margin-top: 1em"><b>X11
|
|
systems</b> <br>
|
|
This function indicates the following errors on systems
|
|
using an X11 server for graphics management:</p>
|
|
|
|
<table width="100%" border="0" rules="none" frame="void"
|
|
cellspacing="0" cellpadding="0">
|
|
<tr valign="top" align="left">
|
|
<td width="11%"></td>
|
|
<td width="9%">
|
|
|
|
|
|
<p><b>ECHILD</b></p></td>
|
|
<td width="2%"></td>
|
|
<td width="78%">
|
|
|
|
|
|
<p>Error when trying to create the child process (see
|
|
<b>NOTES</b> below).</p></td></tr>
|
|
</table>
|
|
|
|
<p style="margin-left:11%;"><b>ECONNREFUSED</b></p>
|
|
|
|
<p style="margin-left:22%;">Failed to connect to the X
|
|
server. This most likely means that your program is not run
|
|
in a graphical environment (for example, it may be run from
|
|
the Linux virtual console).</p>
|
|
|
|
<table width="100%" border="0" rules="none" frame="void"
|
|
cellspacing="0" cellpadding="0">
|
|
<tr valign="top" align="left">
|
|
<td width="11%"></td>
|
|
<td width="7%">
|
|
|
|
|
|
<p><b>EPIPE</b></p></td>
|
|
<td width="4%"></td>
|
|
<td width="78%">
|
|
|
|
|
|
<p>Child process pipe creation failure (see <b>NOTES</b>
|
|
below).</p> </td></tr>
|
|
</table>
|
|
|
|
<p style="margin-left:11%; margin-top: 1em"><b>Win32
|
|
systems</b> <br>
|
|
This function indicates the following errors on Windows
|
|
systems:</p>
|
|
|
|
<table width="100%" border="0" rules="none" frame="void"
|
|
cellspacing="0" cellpadding="0">
|
|
<tr valign="top" align="left">
|
|
<td width="11%"></td>
|
|
<td width="9%">
|
|
|
|
|
|
<p style="margin-top: 1em"><b>EAGAIN</b></p></td>
|
|
<td width="2%"></td>
|
|
<td width="78%">
|
|
|
|
|
|
<p style="margin-top: 1em">Another process has opened the
|
|
clipboard currently.</p></td></tr>
|
|
</table>
|
|
|
|
<p style="margin-left:11%;"><b>ECANCELED</b></p>
|
|
|
|
<p style="margin-left:22%;">Unexpected function failure
|
|
after using a Windows API function as advertised by a prior
|
|
return value. Encountering this <i>errno</i> value might
|
|
indicate a bug in <i>tinyclipboard</i>.</p>
|
|
|
|
<table width="100%" border="0" rules="none" frame="void"
|
|
cellspacing="0" cellpadding="0">
|
|
<tr valign="top" align="left">
|
|
<td width="11%"></td>
|
|
<td width="9%">
|
|
|
|
|
|
<p><b>EINVAL</b></p></td>
|
|
<td width="2%"></td>
|
|
<td width="58%">
|
|
|
|
|
|
<p>The <i>text</i> argument was not valid UTF-8.</p></td>
|
|
<td width="20%">
|
|
</td></tr>
|
|
</table>
|
|
|
|
<p style="margin-left:11%;"><b>ENOTSUP</b></p>
|
|
|
|
<p style="margin-left:22%;">Creation of the invisible GUI
|
|
window (see <b>NOTES</b> below) failed.</p>
|
|
|
|
<h2>EXAMPLES
|
|
<a name="EXAMPLES"></a>
|
|
</h2>
|
|
|
|
|
|
<p style="margin-left:11%; margin-top: 1em"><b>Writing a
|
|
string into the clipboard</b> <br>
|
|
This example writes a static string into the operating
|
|
system’s clipboard.</p>
|
|
|
|
<p style="margin-left:17%; margin-top: 1em"><b>#include
|
|
<stdio.h> <br>
|
|
#include <errno.h> <br>
|
|
#include <tinyclipboard.h></b></p>
|
|
|
|
<p style="margin-left:17%; margin-top: 1em"><b>int main() {
|
|
<br>
|
|
if (tiny_clipwrite("This is an example.") < 0)
|
|
{ <br>
|
|
perror("Failed to write clipboard"); <br>
|
|
return 1; <br>
|
|
} <br>
|
|
else { <br>
|
|
printf("Wrote clipboard successfully.\n"); <br>
|
|
}</b></p>
|
|
|
|
<p style="margin-left:17%; margin-top: 1em"><b>/* Keep
|
|
program running so it also works on X11 systems without <br>
|
|
* a clipboard manager. */ <br>
|
|
getchar();</b></p>
|
|
|
|
<p style="margin-left:17%; margin-top: 1em"><b>return 0;
|
|
<br>
|
|
}</b></p>
|
|
|
|
<h2>NOTES
|
|
<a name="NOTES"></a>
|
|
</h2>
|
|
|
|
|
|
<p style="margin-left:11%; margin-top: 1em">The clipboard
|
|
is a highly operating-system specific resource. The
|
|
<i>tinyclipboard</i> library strives to hide the
|
|
complexities of certain system’s clipboard systems
|
|
(especially X11’s) behind a set of simple, highlevel
|
|
functions that allow the programmer to uniformly access any
|
|
supported operating system’s clipboard system. This
|
|
highlevel interface sacrifices access to some more granular
|
|
features each of the respective systems provides, but if you
|
|
need these, you should probably not be using a
|
|
cross-platform clipboard library anyway.</p>
|
|
|
|
<p style="margin-left:11%; margin-top: 1em">Across all
|
|
operating systems and graphics stacks, the
|
|
<b>tiny_cipnwrite()</b> and <b>tiny_clipwrite()</b>
|
|
functions do not require your application to be a GUI
|
|
application. However, they open invisible windows to
|
|
interact with the clipboard if it is required. From this
|
|
follows that while you do not have to create your
|
|
application as a GUI application, you have to link in your
|
|
system’s native graphics library (e.g., <b>-lX11</b>
|
|
on Linux) and your users must be running your program in
|
|
their graphical environment. Running your program from a
|
|
Linux virtual console will not work (the functions will
|
|
return -1 and set <i>errno</i> to <b>ECONNREFUSED</b>).</p>
|
|
|
|
<p style="margin-left:11%; margin-top: 1em">What follows
|
|
are descriptions of certain problems that arise with any one
|
|
supported operating system’s clipboard system.</p>
|
|
|
|
<p style="margin-left:11%; margin-top: 1em"><b>X11
|
|
systems</b> <br>
|
|
The X11 clipboard system is really complex. It consists of
|
|
three so-called “selections” that can be
|
|
“owned” at any time by any X client. The owner
|
|
of such a selection is responsible for serving the requests
|
|
other X clients make to him for access of the
|
|
clipboard’s content. As a consequence, <i>the
|
|
clipboard’s content is not a global resource on
|
|
X11</i>. Global is only the knowledge of the client owning
|
|
the selection. Due to this ownership system, the content of
|
|
any selection vanishes if the owner X11 connection dies (=
|
|
the window closes).</p>
|
|
|
|
<p style="margin-left:11%; margin-top: 1em">The three
|
|
selections are called <b>PRIMARY</b>, <b>SECONDARY</b>, and
|
|
<b>CLIPBOARD</b>. The first two are unique to X11 and have
|
|
no counterpart on other graphics systems; the <b>PRIMARY</b>
|
|
selection can be set in most applications by marking text
|
|
with the mouse cursor, and retrieved by pressing the middle
|
|
mouse button. The <b>SECONDARY</b> selection is not used by
|
|
anybody. The <b>CLIPBOARD</b> selection is usually accessed
|
|
via pull-down menus or the well-known key combinations
|
|
<b>CTRL+C</b> and <b>CTRL+V</b>; this is the only selection
|
|
<i>tinyclipboard</i> gives you access to for the sake of
|
|
simplicity. It is also the only selection that ordinary
|
|
users know about.</p>
|
|
|
|
<p style="margin-left:11%; margin-top: 1em">The
|
|
<b>tiny_clipwrite()</b> and <b>tiny_clipnwrite()</b>
|
|
functions on X11 first try to communicate with a special X11
|
|
background program called a “clipboard manager”.
|
|
This is a program intended to solve the vanishing problem
|
|
indicated above; an example for such a program is the
|
|
<b>xclipboard(1)</b> application. These programs announce
|
|
their existance to the X11 server, and capable clients
|
|
— like <b>tiny_clipwrite()</b> and
|
|
<b>tiny_clipnwrite()</b> — query this information. If
|
|
these functions find a clipboard manager exists, they will
|
|
write their <i>text</i> argument into the clipboard manager
|
|
and then return immediately. The clipboard manager takes
|
|
over ownership of the <b>CLIPBOARD</b> selection and from
|
|
now on serves the requests of other X clients.</p>
|
|
|
|
<p style="margin-left:11%; margin-top: 1em">While most
|
|
major X desktop environments come with a clipboard manager
|
|
program this is not necessaryly true for small desktop
|
|
environments or individual program combinations. Even
|
|
experienced Linux users do not know about the existance of a
|
|
clipboard manager, and every once in a while they wonder why
|
|
their clipboard content vanishes on their own system, while
|
|
for example it doesn’t do that on a major Linux
|
|
distribution. The <b>tiny_clipwrite()</b> and
|
|
<b>tiny_clipnwrite()</b> functions thus do not give up if
|
|
there is no clipboard manager available. Instead, they call
|
|
<b>fork(2)</b> to create a subprocess, have this subprocess
|
|
create an invisible X11 client window, and set this window
|
|
to be the owner of the <b>CLIPBOARD</b> selection. They then
|
|
communicate the desired content of the selection via a pipe
|
|
to the child process. Any further calls to the two functions
|
|
will skip the call to <b>fork(2)</b> if the child process
|
|
still exists and instead write the clipboard data directly
|
|
onto the pipe, where the child process notices it. When the
|
|
child now receives a clipboard access request, it replies
|
|
with the current “content” of the clipboard,
|
|
i.e. the <i>text</i> argument of the last call to one of the
|
|
two functions.</p>
|
|
|
|
<p style="margin-left:11%; margin-top: 1em">As soon as the
|
|
parent process finishes or the clipboard ownership is taken
|
|
away from the child process (e.g., by hitting <b>CTRL+C</b>
|
|
in another window and thus making that window the owner of
|
|
<b>CLIPBOARD</b>), the child process exits. As the child
|
|
does not decouple from the parent process,
|
|
<b>tiny_clipwrite()</b> and <b>tiny_clipnwrite()</b> install
|
|
an <b>atexit(3)</b> handler that sweeps the process so that
|
|
a zombie process is prevented.</p>
|
|
|
|
<p style="margin-left:11%; margin-top: 1em"><b>Win32
|
|
systems</b> <br>
|
|
The clipboard system on Windows is modelled around a global
|
|
pointer as a resource shared between multiple applications.
|
|
When an application wants to write to the clipboard, it
|
|
first opens the global clipboard resource, excluding
|
|
everybody else from accessing it (even for read access). It
|
|
then empties the clipboard, which causes the Win32
|
|
system’s OS kernel to free the previous global pointer
|
|
(yes, the pointer is freed by the kernel, not by the
|
|
application). The kernel immediately afterwards assigns
|
|
ownership of the clipboard to the calling process, which is
|
|
now obleged to allocate a new buffer, store its data in it,
|
|
and hand the pointer to this buffer over to the clipboard
|
|
system. When done, the process closes the clipboard, but
|
|
formally remains owner of the clipboard until another
|
|
process wants to write into the clipboard or it exits. As
|
|
far as I was able to see, this ownership does not involve
|
|
any duties if one does not use delayed rendering (which
|
|
<i>tinyclipboard</i> does not do).</p>
|
|
|
|
<p style="margin-left:11%; margin-top: 1em">Since the OS
|
|
kernel manages the memory of the clipboard content, the
|
|
content does not vanish if the application closes as it does
|
|
with X11 (see above). Still, to write to the clipboard a
|
|
temporary invisible window is required, which is created by
|
|
<b>tiny_clipwrite()</b> and <b>tiny_clipnwrite()</b> on the
|
|
fly and destroyed before the functions return. This does not
|
|
mean you have to create your Win32 application as a GUI
|
|
application using a <b>WinMain()</b> function; the functions
|
|
are smart enough to create their own GUI space. They will
|
|
work with both console applications and GUI
|
|
applications.</p>
|
|
|
|
<p style="margin-left:11%; margin-top: 1em">It appears to
|
|
be possible to write <b>NUL</b> bytes into the Windows
|
|
clipboard, but it is impossible to retrieve them again from
|
|
there as the clipboard functions available from the Win32API
|
|
do not support querying the size of the clipboard. They
|
|
assume any text on the clipboard is terminated with a
|
|
<b>NUL</b> byte. For the sake of portability, you should
|
|
thus refrain from using <b>NUL</b> bytes in your clipboard
|
|
content if your application needs to run on Windows.</p>
|
|
|
|
<h2>SEE ALSO
|
|
<a name="SEE ALSO"></a>
|
|
</h2>
|
|
|
|
|
|
|
|
<p style="margin-left:11%; margin-top: 1em"><b>tiny_clipread(3)</b></p>
|
|
|
|
<h2>AUTHOR
|
|
<a name="AUTHOR"></a>
|
|
</h2>
|
|
|
|
|
|
<p style="margin-left:11%; margin-top: 1em">The
|
|
<i>tinyclipboard</i> library was written by Marvin
|
|
Gülker <m-guelker@guelkerdev.de>.</p>
|
|
<hr>
|
|
</body>
|
|
</html>
|