Linux Clipboard

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
c_elite
Posts: 3
Joined: Fri Nov 14, 2008 4:35 am

Linux Clipboard

Post by c_elite »

I've noticed that there isn't yet code written for the linux clipboard.
I took the time to see what I could come up with.
I'm not much of an X11 programmer as I've said in the past, but
I'm getting better... :)
Here is a quick (2 full days :) ) implementation of the linux
clipboard to use with the os namespace possibly for getClipboardText();
If anyone has any better ideas let me know... This is just for pasting
to the clipboard...
In order to use this the function PlatformSpecificRun() has to be run
somewhere in a loop so that when other applications request
the clipboard data, the program with this code can give it to them.

I used globals here because I did not find a good way to do it without,
but if anyone has any good ideas, maybe they don't have to be global.

Enjoy! :)

~C_elite

Code: Select all

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/extensions/xf86vmode.h>
#include <X11/keysym.h>

static Window GLOBAL_W = NULL;
static Display *GLOBAL_D = NULL;

static Bool check_if_event_func(Display *d,XEvent *e,XPointer z)
{
    if(e->type == SelectionRequest) { return true; }
    return false;
}

void PlatformSpecificRun()
{
    if(!GLOBAL_D) { GLOBAL_D = XOpenDisplay(NULL); }
    if(!GLOBAL_D) { std::cout << "BAD GLOBAL_D!!!" << std::endl; return; }
    Atom XA_TARGETS = XInternAtom(GLOBAL_D, "TARGETS", 0);
    Atom XA_TEXT = XInternAtom(GLOBAL_D, "TEXT", 0);
    if(!GLOBAL_W)
    {
        GLOBAL_W = XCreateSimpleWindow(GLOBAL_D, DefaultRootWindow(GLOBAL_D), 0, 0, 200, 100, 0, 0, 0);
        XSelectInput(GLOBAL_D, GLOBAL_W, StructureNotifyMask);
    }
    if(!GLOBAL_W) { std::cout << "BAD GLOBAL_W!!!" << std::endl; return; }

    XEvent e, respond;
    XSelectInput(GLOBAL_D, GLOBAL_W, StructureNotifyMask);
    if(!XCheckIfEvent(GLOBAL_D,&e, check_if_event_func, NULL)) { return; }
    
    if(e.type == SelectionRequest)
    {
        if(e.xselectionrequest.target == XA_STRING)
        {
            std::cout << "SELECTIONREQUEST FOR XA_STRING!!!!" << std::endl;
            Atom type;
            unsigned long len = 0;
            unsigned long nbytes = 0;
            unsigned long tmp = 0;
            unsigned char *data = NULL;
            int fmt = 0;
            int res = 0;
            XGetWindowProperty(GLOBAL_D,GLOBAL_W,XA_PRIMARY,0,10000000L,0,XA_STRING,&type,&fmt,&len,&nbytes,&data); 
            res = XChangeProperty(e.xselectionrequest.display,e.xselectionrequest.requestor,e.xselectionrequest.property,e.xselectionrequest.target,8,PropModeReplace,
                                     (unsigned char *)data,len);
            if (res == BadAlloc || res == BadAtom || res == BadMatch || res == BadValue || res == BadWindow)
            {
                fprintf(stderr,"XChangeProperty failed %d\n",res);
            }
            
            respond.xselection.property = e.xselectionrequest.property;
        }
        else if(e.xselectionrequest.target == XA_TARGETS)
        {
            std::cout << "SELECTIONREQUEST FOR XA_TARGETS!!!!" << std::endl;
            Atom type;
            unsigned long len = 0;
            unsigned long nbytes = 0;
            unsigned long tmp = 0;
            unsigned char *data = NULL;
            int fmt = 0;
            int res = 0;

            Atom targets[1];
            targets[0] = (Atom) XA_STRING;
            
            res = XChangeProperty(e.xselectionrequest.display,e.xselectionrequest.requestor,e.xselectionrequest.property,e.xselectionrequest.target,32,PropModeReplace,
                                     (unsigned char *)&targets,1);
            if (res == BadAlloc || res == BadAtom || res == BadMatch || res == BadValue || res == BadWindow)
            {
                fprintf(stderr,"XChangeProperty failed %d\n",res);
            }
            
            respond.xselection.property = e.xselectionrequest.property;
            
            respond.xselection.type = SelectionNotify;
            respond.xselection.display = e.xselectionrequest.display;
            respond.xselection.requestor = e.xselectionrequest.requestor;
            respond.xselection.selection = e.xselectionrequest.selection;
            respond.xselection.target= e.xselectionrequest.target;
            respond.xselection.time = e.xselectionrequest.time;
            int result = XSendEvent(e.xselectionrequest.display, e.xselectionrequest.requestor,0,0L,&respond);
            if (result == BadValue || result == BadWindow) fprintf(stderr,"send SelectionRequest failed\n");
            XFlush(GLOBAL_D);
            return;
        }
        else // Strings only please
        {
            printf ("No String %s\n", XGetAtomName(GLOBAL_D, e.xselectionrequest.target));
            respond.xselection.property= None;
        }
        
        respond.xselection.type = SelectionNotify;
        respond.xselection.display = e.xselectionrequest.display;
        respond.xselection.requestor = e.xselectionrequest.requestor;
        respond.xselection.selection = e.xselectionrequest.selection;
        respond.xselection.target= e.xselectionrequest.target;
        respond.xselection.time = e.xselectionrequest.time;
        int result = XSendEvent(GLOBAL_D, e.xselectionrequest.requestor,0,0L,&respond);
        if (result == BadValue || result == BadWindow) fprintf(stderr,"send SelectionRequest failed\n");
        XFlush(GLOBAL_D);
    }
}

void SetClipboardText(std::string in)
{
    static std::string statstr = "";
    statstr = in;
    
    Atom XA_CLIPBOARD = XInternAtom(GLOBAL_D, "CLIPBOARD", 0);

    if(!GLOBAL_D) { GLOBAL_D = XOpenDisplay(NULL); }
    if(!GLOBAL_D) { std::cout << "BAD GLOBAL_D!!!" << std::endl; return; }
    if(!GLOBAL_W)
    {
        GLOBAL_W = XCreateSimpleWindow(GLOBAL_D, DefaultRootWindow(GLOBAL_D), 0, 0, 200, 100, 0, 0, 0);
        XSelectInput(GLOBAL_D, GLOBAL_W, StructureNotifyMask);
    }
    if(!GLOBAL_W) { std::cout << "BAD GLOBAL_W!!!" << std::endl; return; }
    
    XChangeProperty(GLOBAL_D,GLOBAL_W,XA_PRIMARY,XA_STRING,8, PropModeReplace, (unsigned char *)statstr.c_str(),statstr.length());
    XSetSelectionOwner(GLOBAL_D, XA_CLIPBOARD, GLOBAL_W, CurrentTime);
    XSetSelectionOwner(GLOBAL_D, XA_PRIMARY, GLOBAL_W, CurrentTime)e3;
    if(GLOBAL_W != XGetSelectionOwner(GLOBAL_D,XA_CLIPBOARD)) { fprintf(stderr,"Could not set CLIPBOARD selection.\n"); }
    XFlush(GLOBAL_D);
}
Post Reply