tiny_clipnwrite

NAME
SYNOPSIS
DESCRIPTION
RETURN VALUE
ERRORS
EXAMPLES
NOTES
SEE ALSO
AUTHOR

NAME

tiny_clipwrite, tiny_clipnwrite - Write to the OS clipboard

SYNOPSIS

#include <tiynclipboard.h>

int tiny_clipnwrite(const char* text, int len);
int tiny_clipwrite
(const char* text);

DESCRIPTION

The tiny_clipnwrite() function reads len bytes from the string buffer pointed to by text 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 NUL bytes into the clipboard. It is your responsibility to set the len argument accordingly. text is expected to be encoded in UTF-8 regardless of the current locale’s encoding.

The tiny_clipwrite() function behaves like the tiny_clipnwrite() function, except that it determines the length of the string to write to the clipboard by utilising the strlen(3) function on its text argument. It is thus not possible to copy a string containing NUL bytes into the clipboard using this function; use tiny_clipnwrite() if you need to do this.

RETURN VALUE

The tiny_clipnwrite() and tiny_clipwrite() functions return 0 if the data was written successfully into the operating system’s clipboard. Otherwise they return -1 and set errno to indicate the error.

ERRORS

X11 systems
This function indicates the following errors on systems using an X11 server for graphics management:

ECHILD

Error when trying to create the child process (see NOTES below).

ECONNREFUSED

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).

EPIPE

Child process pipe creation failure (see NOTES below).

Win32 systems
This function indicates the following errors on Windows systems:

EAGAIN

Another process has opened the clipboard currently.

ECANCELED

Unexpected function failure after using a Windows API function as advertised by a prior return value. Encountering this errno value might indicate a bug in tinyclipboard.

EINVAL

The text argument was not valid UTF-8.

ENOTSUP

Creation of the invisible GUI window (see NOTES below) failed.

EXAMPLES

Writing a string into the clipboard
This example writes a static string into the operating system’s clipboard.

#include <stdio.h>
#include <errno.h>
#include <tinyclipboard.h>

int main() {
if (tiny_clipwrite("This is an example.") < 0) {
perror("Failed to write clipboard");
return 1;
}
else {
printf("Wrote clipboard successfully.\n");
}

/* Keep program running so it also works on X11 systems without
* a clipboard manager. */
getchar();

return 0;
}

NOTES

The clipboard is a highly operating-system specific resource. The tinyclipboard 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.

Across all operating systems and graphics stacks, the tiny_cipnwrite() and tiny_clipwrite() 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., -lX11 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 errno to ECONNREFUSED).

What follows are descriptions of certain problems that arise with any one supported operating system’s clipboard system.

X11 systems
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, the clipboard’s content is not a global resource on X11. 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).

The three selections are called PRIMARY, SECONDARY, and CLIPBOARD. The first two are unique to X11 and have no counterpart on other graphics systems; the PRIMARY selection can be set in most applications by marking text with the mouse cursor, and retrieved by pressing the middle mouse button. The SECONDARY selection is not used by anybody. The CLIPBOARD selection is usually accessed via pull-down menus or the well-known key combinations CTRL+C and CTRL+V; this is the only selection tinyclipboard gives you access to for the sake of simplicity. It is also the only selection that ordinary users know about.

The tiny_clipwrite() and tiny_clipnwrite() 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 xclipboard(1) application. These programs announce their existance to the X11 server, and capable clients — like tiny_clipwrite() and tiny_clipnwrite() — query this information. If these functions find a clipboard manager exists, they will write their text argument into the clipboard manager and then return immediately. The clipboard manager takes over ownership of the CLIPBOARD selection and from now on serves the requests of other X clients.

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 tiny_clipwrite() and tiny_clipnwrite() functions thus do not give up if there is no clipboard manager available. Instead, they call fork(2) to create a subprocess, have this subprocess create an invisible X11 client window, and set this window to be the owner of the CLIPBOARD 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 fork(2) 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 text argument of the last call to one of the two functions.

As soon as the parent process finishes or the clipboard ownership is taken away from the child process (e.g., by hitting CTRL+C in another window and thus making that window the owner of CLIPBOARD), the child process exits. As the child does not decouple from the parent process, tiny_clipwrite() and tiny_clipnwrite() install an atexit(3) handler that sweeps the process so that a zombie process is prevented.

Win32 systems
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 tinyclipboard does not do).

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 tiny_clipwrite() and tiny_clipnwrite() 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 WinMain() function; the functions are smart enough to create their own GUI space. They will work with both console applications and GUI applications.

It appears to be possible to write NUL 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 NUL byte. For the sake of portability, you should thus refrain from using NUL bytes in your clipboard content if your application needs to run on Windows.

SEE ALSO

tiny_clipread(3)

AUTHOR

The tinyclipboard library was written by Marvin Gülker <m-guelker@guelkerdev.de>.