Clipboard problem solved

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



ok after 3 or 4 weeks I figured out how to use the clipboard in X: and here I am reporting my results so that other people may not suffer:

How to get text data from the clipboard (paste):

//for some reason unknown only to mortals, XA_CLIPBOARD is not an internal atom defined in Xatom.h
XA_CLIPBOARD = XInternAtom(PStatus.xdisplay, "CLIPBOARD", 0);


txwin=XGetSelectionOwner(PStatus.xdisplay,XA_CLIPBOARD);
//txwin is the xwindow that owns the specified selection (XA_CLIPBOARD)
//fprintf(stderr,"Current owner of XA_CLIPBOARD=%p\n",txwin);
//to get data from XA_CLIPBOARD and put in XA_PRIMARY property
//if no owner, this program will get SelectionRequest and send
//whatever is in XA_PRIMARY, which will be an empty string
if (txwin) {
XConvertSelection(PStatus.xdisplay,XA_CLIPBOARD,XA_STRING,XA_PRIMARY,twin->xwindow,CurrentTime);
}
XGetWindowProperty(PStatus.xdisplay,twin->xwindow,XA_PRIMARY,0,10000000L,0,XA_STRING,&type,&format,&len,&bytes_left,&data);


//data will have the string

  XFree(data);
  XFlush(PStatus.xdisplay);





//to copy we have to own the XA_CLIPBOARD selection
//(why not just make CLIPBOARD a property and do a GetProperty from the CLIPBOARD owner?)
//to send windows that request this data the text from this window
//This text, for example, data can be stored anywhere, but I chose to store it in
//the XA_PRIMARY selection property


//I guess in this way, any window that wants to write to the clipboard has to
//own the XA_CLIPBOARD selection, and then handle SelectionRequest events to send
//any other client (xwindow program) that data, until some other xwindow needs to copy
//data to the clipboard, and then must own XA_CLIPBOARD


//copy string to PRIMARY property of twin
//in SelectionRequest event handler,
//this program will send XA_PRIMARY to any window that requests data from XA_CLIPBOARD
XChangeProperty(PStatus.xdisplay,twin->xwindow,XA_PRIMARY,XA_STRING,
8, PropModeReplace, (unsigned char *)tcontrol->text2,strlen(tcontrol->text2));


//make this window own the clipboard selection
XSetSelectionOwner(PStatus.xdisplay,XA_CLIPBOARD,twin->xwindow,CurrentTime);
if (twin->xwindow!=XGetSelectionOwner(PStatus.xdisplay,XA_CLIPBOARD))
fprintf(stderr,"Could not get CLIPBOARD selection.\n");
XFlush(PStatus.xdisplay);
---------------------
In the event handler:
(only XNextEvent would get SelectionNotify events, XCheckWindowEvent would not)
case SelectionRequest:
/*
The X server reports SelectionRequest events to the owner of a selection. The X server generates this event whenever a client requests a selection conversion by calling XConvertSelection() for the owned selection.
*/
//Somebody wants our data


fprintf(stderr,"Selection Request\n");
fprintf(stderr,"twin=%x\n",(u32)twin->xwindow);
fprintf(stderr,"Requester=%x selection=%d target=%d property=%d\n",(u32)xevent.xselectionrequest.requestor,(i32)xevent.xselectionrequest.selection,(i32)xevent.xselectionrequest.target,(i32)xevent.xselectionrequest.property);
fprintf(stderr,"target=%s\n",XGetAtomName(PStatus.xdisplay,xevent.xselectionrequest.target));
fprintf(stderr,"property=%s\n",XGetAtomName(PStatus.xdisplay,xevent.xselectionrequest.property));
// test=malloc(100);
// strcpy(test,"This is a test.");


XGetWindowProperty(PStatus.xdisplay,twin->xwindow,XA_PRIMARY,0,10000000L,0,XA_STRING,&type,&format,&len,&bytes_left,&data); fprintf(stderr,"twin primary type=%d format=%d len=%d data=%s\n",(i32)type,format,(i32)len,data);


//Try to change the property
//Put the XA_PRIMARY string into the requested property of requesting window
result=XChangeProperty(PStatus.xdisplay,xevent.xselectionrequest.requestor,xevent.xselectionrequest.property,xevent.xselectionrequest.target,8,PropModeReplace,
(unsigned char *)data,len);
if (result == BadAlloc
|| result == BadAtom || result == BadMatch
|| result == BadValue || result == BadWindow)
{
fprintf(stderr,"XChangeProperty failed %d\n",result);
}


free(test);

     //make SelectionNotify event
     xev.type = SelectionNotify;
     xev.send_event = True;
     xev.display = PStatus.xdisplay;
     xev.requestor = xevent.xselectionrequest.requestor;
     xev.selection = xevent.xselectionrequest.selection;
     xev.target = xevent.xselectionrequest.target;
     xev.property = xevent.xselectionrequest.property;
     xev.time = xevent.xselectionrequest.time;

//Send message to requesting window that operation is done
result = XSendEvent (PStatus.xdisplay,xev.requestor,0,0L,(XEvent *) &xev);
if (result==BadValue || result==BadWindow)
fprintf(stderr,"send SelectionRequest failed\n");


break;






------------------------ Here is more misc data:

//difference between selection and property
properties are easy, each window has a variety of propreties (some can be custom, and many are standard) they can be listed with:
//List all properties of this window
AtomList=XListProperties(PStatus.xdisplay,txwin,&numprop);
while(numprop>-1) {
fprintf(stderr,"Property %d\n",AtomList[numprop-1]);
fprintf(stderr,"%s\n",XGetAtomName(PStatus.xdisplay,AtomList[numprop-1]));
XGetWindowProperty(PStatus.xdisplay,txwin,AtomList[numprop-1],0,10000000L,0,AnyPropertyType,&type,&format,&len,&bytes_left,&data); fprintf(stderr,"type=%d format=%d len=%d data=%s\n",type,format,len,data);
numprop--;
}


a selection, I guess, is not directly readable (for example XGetWindowProperty(,,XA_CLIPBOARD,..), although you can write and read this XA_CLIPBOARD property, the property XA_CLIPBOARD does not contain the text in the clipboard. the XA_CLIPBOARD selection has the clipboard text and cannot be read with a XGetWindowProperty (how about a XGetWindowSelection already? to get that clipboard data)

why not XGetProperty
XSetProperty?  instad of XChangeProperty


PRIMARY and SECONDARY are selection properties so they are xwindow properties



XConvertSelection should be more like XMoveSelectionToProperty, if anything, but possibly XGetSelection should have been implemented instead



I saw an example for a different operating system that had the XA_CLIPBOARD as a property for the root window, which makes sense because then the main root XWindow would always be the place to get or set data in the clipboard (no event processing would be needed).


----------
I think as a final comment, how about some simple test code examples in the X documentation?



Enjoy! Ted

--
Ted Huntington
Programmer Analyst I
Main Library
University of California, Irvine
PO Box 19557
Irvine, CA 92623-9557
emesgs: thunting@xxxxxxx
web page: http://business.lib.uci.edu/webpages/ted.htm
8:00a-12:00p Business Office (949) 824-8926 1:00p-5:00p Multimedia Resource Center (949) 824-1674 "Stop violence, teach science."



_______________________________________________ XFree86 mailing list XFree86@xxxxxxxxxxx http://XFree86.Org/mailman/listinfo/xfree86

[Index of Archives]     [X Forum]     [Xorg]     [XFree86 Newbie]     [IETF Announce]     [Security]     [Font Config]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux Kernel]

  Powered by Linux