New clipboard proposal

Philip Van Hoof spamfrommailing at freax.org
Wed Jan 5 00:09:31 EET 2005


On Tue, 2005-01-04 at 17:46 +0100, Philip Van Hoof wrote:

> I am also playing with the idea of adding hooks to the xlib functions
> related to copy and pasting. Maybe it's even possible to do all this in
> xlib (or the newer xcb/xcl) and by that not breaking any backwards
> compatibility. Even make it possible to let the old xclients use a new
> technique without any changes necessary except of course relinking.

Humble ..

It's my first time I've been reading X11/Xlib code so its likely I have
many things wrong. I'm also introducing a few new functions. They
haven't been made of course. But you'll get the idea.

I think something like that would need two hooks. One in GetProp.c
(XGetWindowProperty) and one in ConvSel.c (XConvertSelection). Both for
the requester

If a SelectionRequest happens, it needs to handle that event by
preparing what will be available on the IPC (bus). This is for the
owner.

I agree that it's totally a hack. It's not clean. It's playing and
messing around. I fear, however, there's few ways to maintain backwards
compatibility while fixing the current clipboard issues.

.
.
.


In pseudo

The first hook would look like this [..] The second hook would only have
to store the arguments of XConvertSelection to a, for the plugin,
temporary global struct (and free the last one if any).

[..] in GetProp.c (for example at line 50):


XGetWindowProperty (...)
{

...

if (thepluginisloaded && selextension_hooks->XGetWindowProperty_Hook)
{

    // This is a functionpointer which isn't NULL if it's implemented

    XReplyInfo *i = selextension_hooks->XGetWindowProperty_Hook (...);

    // It will return NULL, however, if the IPC-mechanism failed

    if (i != NULL) {

      // The function returned all this by parsing it from what we
      // received over our IPC.

      *actual_type = i->propertyType;
      *actual_format = i->format;
      *nitems = i->nItems;
      *bytesafter = i->bytesAfter;
      *prop = i->received;
 

       return Success;
    }

    // In which case we fallback
}

// If there's no plugin or function: fallback (so totally nothing
// changes)

...

}

Pseudo code implementation of that functionpointer (XGetWindowProperty_
Hook) in a plugin:

XReplyInfo * XGetWindowProperty_Hook
    (dpy, w, property, offset, length, delete, 
     req_type, actual_type, actual_format, nitems, 
     bytesafter, prop)
...
{

  Atom CLIPBOARD = XInternAtom (dpy, "CLIPBOARD", 0);
  Atom PRIMARY = XInternAtom (dpy, "PRIMARY", 0);
  Atom SECONDARY = XInternAtom (dpy, "SECONDARY", 0);

  // our new target
  Atom IPCINFO = XInternAtom (dpy, "selection-extension/ipcinfo", 0);

  if (property == CLIPBOARD || property == PRIMARY) {
    unsigned char **ipcinfo;
    xGetPropertyReply reply;
    register xGetPropertyReq *req;

    // First in stead of the original request, we request 
    // the "selection-extension/ipcinfo"-target 

    // Using that target we might get the information about the
    // IPC-mechanism that might be available

    XConvertSelection (dpy, property, IPCINFO, w, CurrentTime);

    LockDisplay(dpy);
    GetReq (GetProperty, req);
    req->window = w;
    req->property = property;
    req->type = req_type;
    req->delete = delete;
    req->longOffset = offset;
    req->longLength = length;

    _XReply (dpy, (xReply *) &reply, 0, xFalse);
   
     if (reply.propertyType != None) {

         // This is cool since it means we received it

         // Simplified for this mail, assuming reply.format is always 8
 
         *prop = Xmalloc (reply.nitems + 1);
        _XReadPad (dpy, (char *) *ipcinfo, reply.nItems);

        if (IpcinfoDisplaystring (ipcinfo) == Displaystring (dpy))
        {
           // This is even more cool since it means we live on the same
           // host as the xclient who gave us the special target

           // So .. we are going to use the IPC-mechanism

           // wanted_selection_info is what we stored using the
           // XConvertSelection hook

           return GetDataUsingIpc (ipcinfo, wanted_selection_info);
        }
     }

   // In any other case fallback.

   // If GetdataUsingIpc returns NULL (who knows), it will also fallback

   // This is the global struct stored using the XConvertSelection hook

   WantedSelInfo *i = wanted_selection_info;


   // The most ugly part

   // Because we just screwed the original request, we re-request it
   // as if nothing happened

   XConvertSelection (i->dpy, i->property, i->target, i->w, i->time);

   return NULL;
}


> Puttings those hooks there also doesn't necessarily mean depending on
> the code of those hooks (like DBUS code). This can also be implemented
> as a library of which the functions, if the library is found and the
> functions are implemented, are invoked. Basically just like what I'm
> doing with [see above and checkout it's source]: Using some
> functionpointers and checking for an implementation (easy stuff).



-- 
Philip Van Hoof, Software Developer @ Cronos
home: me at freax dot org
gnome: pvanhoof at gnome dot org
work: philip dot vanhoof at cronos dot be
junk: philip dot vanhoof at gmail dot com
http://www.freax.be, http://www.freax.eu.org




More information about the xdg mailing list