weblog d’un abbe

20060805

X Cut-and-Paste aka X Clipboard

Filed under: Research — Tags: , , , , , — abbe @ 0240

As, I’ve completely migrated myself to Linux, few months ago and started using Linux (& FreeBSD) regularly. I find one thing quite strange (Unknown to me) in X (as I was a Microsoft Windows user in past ), i.e. Clipboard . Clipboard in X works differently and it is not integrated in X Window System. To me it looks like a hack built on top of X Window System.

What I find strange is you can also copy-paste text without explicitly copy-pasting ( i.e. no Ctrl+C + Ctrl+V or Edit|Copy + Edit|Paste ) text. You just select the text from source window, and middle click on the destination window, text will get copied implicitly and pasted. And if you’ve already copied some text previously via explicit copy it is also retained (not destroyed) after implicit copy. Isn’t this interesting.

Well more details can be found on jwz‘s article titled X Selections, Cut Buffers, and Kill Rings. Inspired from his article, I’ve wrote the following C program (requires Xlib) which currently just prints the WM_NAME property of the window currently owning the specific selections.

/**
 * clip.c
 * to compile and link (on X11R7): cc -o clip clip.c -lX11
 * to compile and link (on X11R6): cc -o clip clip.c -L/usr/X11R6/lib{libsuffix} -I/usr/X11R6/include -lX11
 * where libsuffix is 32 or 64 or 128 ( I wish I will get a chance to compile on this architecture ) 
 * depending on your machine word size.
 */
#include <stdio.h>
#include <stdlib.h>

#include <X11/Xlib.h>

#define s_PRIMARY   "PRIMARY"
#define s_CLIPBOARD "CLIPBOARD"

static Atom get_atom(Display*, const char*);
static void print_stuff0(Display*, Atom);

int
main()
{
  Atom a_Primary, a_Clipboard;
  Display* display = NULL;
  char* display_name = NULL;
  char* window_name = NULL;
  Window win;

  if(!(display = XOpenDisplay(display_name)))
    {
      fprintf(stderr, "Error opening %s\n", XDisplayName(display_name));
      return 0;
    }

  a_Primary = get_atom(display, s_PRIMARY);
  a_Clipboard = get_atom(display, s_CLIPBOARD);
 

  print_stuff0(display, a_Primary);
  print_stuff0(display, a_Clipboard);

  XCloseDisplay(display);
}

void
print_stuff0(Display* display, Atom atom)
{
  Window win;
  char* window_name;
  char* atom_name;

  atom_name = XGetAtomName(display, atom);

  if((win = XGetSelectionOwner(display, atom)) != None)
    {

      XFetchName(display, win, &window_name);
      printf("\"%s\" (WM_NAME of %ld) owns selection of \"%s\" atom.\n", window_name, win, atom_name);
      XFree(window_name);
    }
  else
      printf("No body owns selection \"%s\"\n", atom_name);

}

Atom 
get_atom(Display* display, const char* atom)
{
  Atom a;
  if((a = XInternAtom(display, atom, True)) == None)
    {
      fprintf(stderr, "Oops, \"%s\" atom doesn't exists.\n", atom);
      XCloseDisplay(display);
      exit(2);
    }

  return a;

}

jwz aka Jamie W. Zawinski hacked most of the XScreenSaver stuff and he also contributed to projects like Mozilla, XEmacs etc. The articles on his website and homepage of his website are really cool :-). Just bookmark it.

Advertisements

2 Comments »

  1. Hey, Good stuff. I will find this explicit, implicity copy thing useful at times.

    Comment by Edwin — 20060821 @ 1121

  2. I also find copy-paste thing useful at times ;)

    Comment by आशीष शुक्ला — 20060821 @ 1324


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: