2009-12-08 14 views
8

ओएस एक्स पर चौखटे का उपयोग करना, मैं पेस्टबोर्ड को एक PNG कॉपी करने के लिए निम्नलिखित का उपयोग कर सकते (सी में - स्पष्ट रूप से मैं कोको के साथ NSPasteboard इस्तेमाल कर सकते हैं):एक्स 11 के साथ क्लिपबोर्ड पर कैसे कॉपी करें?

#include <ApplicationServices/ApplicationServices.h> 

int copyThatThing(void) 
{ 
    PasteboardRef clipboard; 
    if (PasteboardCreate(kPasteboardClipboard, &clipboard) != noErr) { 
     return -1; 
    } 

    if (PasteboardClear(clipboard) != noErr) { 
     CFRelease(clipboard); 
     return -1; 
    } 

    size_t len; 
    char *pngbuf = createMyPNGBuffer(&len); /* Defined somewhere else */ 
    if (pngbuf == NULL) { 
     CFRelease(clipboard); 
     return -1; 
    } 

    CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, pngbuf, 
             len, kCFAllocatorNull); 
    if (data == NULL) { 
     CFRelease(clipboard); 
     free(pngbuf); 
     return -1; 
    } 

    OSStatus err; 
    err = PasteboardPutItemFlavor(clipboard, NULL, kUTTypePNG, data, 0); 
    CFRelease(clipboard); 
    CFRelease(data); 
    free(pngbuf); 

    return 0; 
} 

मैं करने के लिए इस कार्यक्षमता पोर्टिंग में दिलचस्पी रखता हूँ लिनक्स/* बीएसडी प्लेटफ़ॉर्म। एक्स का उपयोग करके मैं इसे कैसे दोहरा सकता हूं?

उत्तर

10

किसी भी अन्य चीज़ से पहले X Selections, Cut Buffers, and Kill Rings पढ़ें। एक्स 11 की एक अनूठी प्रणाली है जिसे किसी और ने कॉपी नहीं किया है।

अधिकतर अन्य प्रणालियों से अलग एक विषमता: यदि चयन का चयन करने वाला प्रोग्राम (क्लिपबोर्ड) चला जाता है, तो चयन भी करता है। तो जब आपका प्रोग्राम कहता है "मेरे पास एक चयन है (जो एक छवि होता है)" और फिर निकलता है, कोई भी उस छवि की प्रतिलिपि आपके लिए अनुरोध करने में सक्षम नहीं होगा। उपयोगी होने के लिए, क्लिपबोर्ड मालिक को कम से कम तब तक चिपकने की आवश्यकता होती है जब तक कि कोई अन्य प्रोग्राम चयन न करे।

अभी भी यहाँ? यहां एक छोटा प्रोग्राम है जो आप चाहते हैं कि पीजीजीटीके का उपयोग करके (क्योंकि सी दर्द है)।

#!/usr/bin/env python 
import gtk 
import sys 

count = 0 
def handle_owner_change(clipboard, event): 
    global count 
    print 'clipboard.owner-change(%r, %r)' % (clipboard, event) 
    count += 1 
    if count > 1: 
     sys.exit(0) 

image = gtk.gdk.pixbuf_new_from_file(sys.argv[1]) 
clipboard = gtk.clipboard_get() 
clipboard.connect('owner-change', handle_owner_change) 
clipboard.set_image(image) 
clipboard.store() 
gtk.main() 

क्या हुड के नीचे होता है:

  • को जरूर एक छवि लोड करता है।
  • जीटीके क्लाइबोर्ड चयन के स्वामित्व का दावा करता है।
  • जीटीके requests कि CLIPBOARD_MANAGER प्रतिलिपि बनाएँ और चयन करें। (हो सकता है कि कोई नहीं चल रहा हो, इसलिए ऐसा नहीं हो सकता है।)
  • जब कोई अन्य प्रोग्राम हमारे चयन से डेटा का अनुरोध करता है, तो जीटीके छवि से रूपांतरण के डेटा को रूपांतरण और हस्तांतरण को संभालता है।
  • पहला OWNER_CHANGE ईवेंट हमारे स्वामित्व लेने के अनुरूप है; स्वामित्व खोने और बाहर निकलने के लिए संबंधित अगले के लिए प्रतीक्षा करें।

यदि कोई क्लिपबोर्ड प्रबंधक चल रहा है, तो यह प्रोग्राम तुरंत बाहर निकल सकता है। अन्यथा, यह तब तक इंतजार करेगा जब तक कि "कट/प्रतिलिपि" किसी अन्य कार्यक्रम में नहीं किया जाता है।

+0

बहुत बहुत धन्यवाद। कंपिज़ स्क्रीनशॉट उपकरण के साथ बहुत उपयोगी! – Drasill

+0

साफ स्क्रिप्ट! सुपरसियर पर निम्न प्रविष्टि में एक समान पायथन लिपि भी शामिल है, लेकिन यह केवल gnome के अंतर्गत काम करता है: http://superuser.com/questions/301851/how-to-copy-a-picture-to-clipboard-from-command-line -इन-लिनक्स – qed

+0

यद्यपि इसमें सुधार किया जा सकता है। उदाहरण के लिए, क्लिपबोर्ड में सामग्री चिपक जाने के बाद, क्या हम इसे स्वचालित रूप से gtk.main को मार सकते हैं? – qed

3

प्रोग्राम समाप्त होने के बाद जीटीके क्लिपबोर्ड पर डेटा स्टोर करने की क्षमता अच्छी तरह से समर्थित नहीं है। GTK.clipboard.store बड़ी छवियों (कई सौ केबी से अधिक) को स्टोर करने में असफल हो सकता है, और कंपोज़ जैसी उन्नत डेस्कटॉप सुविधाएं इस तंत्र के साथ संघर्ष कर सकती हैं। इन दोषों के बिना एक समाधान पृष्ठभूमि में एक साधारण gtk अनुप्रयोग चलाने के लिए है।


#! /usr/bin/env python 
# gclipboard-imaged.py 
import gtk, sys, threading; 
import Pyro.core; 

class ImageToClipboard(Pyro.core.ObjBase): 
    def __init__(self, daemon): 
     Pyro.core.ObjBase.__init__(self) 
     self.daemon = daemon; 
    def _set_image(self, img): 
     clp = gtk.clipboard_get(); 
     clp.set_image(img); 
    def set_image_from_filename(self, filename): 
     with gtk.gdk.lock: 
     img = gtk.gdk.pixbuf_new_from_file(filename); 
     self._set_image(img); 
    def quit(self): 
     with gtk.gdk.lock: 
     gtk.main_quit(); 
     self.daemon.shutdown(); 

class gtkThread(threading.Thread): 
    def run(self): 
     gtk.main(); 

def main(): 
    gtk.gdk.threads_init(); 
    gtkThread().start(); 
    Pyro.core.initServer(); 
    daemon = Pyro.core.Daemon(); 
    uri = daemon.connect(ImageToClipboard(daemon),"imagetoclipboard") 
    print "The daemon running on port:",daemon.port 
    print "The object's uri is:",uri 
    daemon.requestLoop(); 
    print "Shutting down." 
    return 0; 

if __name__=="__main__": 
    sys.exit(main()) 

प्रारंभ इस कार्यक्रम के लिए एक पृष्ठभूमि प्रक्रिया के रूप में, यानी

gclipboard-imaged.py &

निम्न उदाहरण ग्राहक: निम्नलिखित अजगर सर्वर अनुप्रयोग Pyro पैकेज ImageToClipboard के तरीकों का पर्दाफाश करने का उपयोग करता है एप्लिकेशन कमांड लाइन पर दिए गए फ़ाइल नाम का उपयोग करके क्लिपबोर्ड छवि सेट करता है:


#! /usr/bin/env python 
# gclipboard-setimage.py 
import Pyro.core, sys; 

serverobj = Pyro.core.getProxyForURI("PYROLOC://localhost:7766/imagetoclipboard"); 
filename = sys.argv[1]; 
serverobj.set_image_from_filename(filename); 

एक प्रतिलिपि बनाने के लिए क्लिपबोर्ड पर mage,

gclipboard-setimage.py picname.png

+0

यह थोड़ा जटिल है, लेकिन निश्चित रूप से नीचे वोट के लायक नहीं है। अपना समाधान पोस्ट करने के लिए धन्यवाद! – qed

संबंधित मुद्दे