2009-12-08 8 views
8

私はペーストボードにPNGをコピーするには、次を使用することができ、OS Xのフレームワークを使用する(Cで - 明らかに私はココアでNSPasteboardを使用することができます):私はこの機能を移植することに興味X11でクリップボードにコピーするには?

#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; 
} 

Linux/* BSDプラットフォームXを使ってこれをどのように複製できますか?

答えて

10

他のものより先にX Selections, Cut Buffers, and Kill Ringsに行ってください。 X11は他の誰もコピーしていないような独特のシステムを持っています。

他のほとんどのシステムとは異なる奇妙なこと:選択(クリップボード)を所有するプログラムがなくなると、その選択も消えます。だからあなたのプログラムが「私は選択された画像を持っている」と言って終了すると、誰もあなたからその画像のコピーをリクエストすることはできません。有用であるためには、クリップボードの所有者は、少なくとも別のプログラムが選択を取るまで、執着する必要があります。

まだここにありますか? PyGTKを使って、あなたが望むことをする短いプログラムがあります(Cは痛みです)。

  • たGdkは、イメージをロード:ボンネットの下に何が起こる

    #!/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() 
    

  • GtkはCLIPBOARD選択の所有権を主張しています。
  • Gtk requests CLIPBOARD_MANAGERがコピーして選択します。
  • 他のプログラムが私たちの選択からデータを要求すると、Gtkはイメージからターゲットへのデータの変換と転送を処理します。
  • 最初のOWNER_CHANGEイベントは、所有権を取得する私たちに対応しています。所有権を失っている私たちに対応する次のものを待って、終了してください。

クリップボードマネージャが実行されている場合、このプログラムはすぐに終了することがあります。それ以外の場合は、別のプログラムで「カット/コピー」が実行されるまで待機します。

+0

ありがとう。 compizのスクリーンショットツールで非常に便利です! – Drasill

+0

きちんとしたスクリプト!スーパーユーザーの次のエントリにも同様のpythonスクリプトが含まれていますが、gnomeでのみ動作します。http://superuser.com/questions/301851/how-to-copy-a-picture-to-clipboard-from-commandline -in-linux – qed

+0

これを改善する方法があります。たとえば、クリップボードのコンテンツをペーストした後、gtk.mainを自動的に削除することはできますか? – qed

3

プログラムの終了後にGTKクリップボードにデータを保存する機能は十分サポートされていません。 GTK.clipboard.storeは大きな画像(数百kBより大きい)を保存することができず、compizのような高度なデスクトップ機能がこのメカニズムと競合する可能性があります。これらの欠点のないソリューションの1つは、バックグラウンドでシンプルなgtkアプリケーションを実行することです。次のPythonサーバアプリケーションはImageToClipboardのメソッドを公開するために、パイロパッケージを使用しています。


#! /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 &

次の例では、クライアントアプリケーションは、コマンドラインで指定されたファイル名を使用してクリップボードイメージを設定します。


#! /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); 

iをコピーするにはメイジをクリップボードに貼り付けて、

gclipboard-setimage.py picname.png

+0

これは少し複雑ですが、間違いなく投票に値するわけではありません。あなたのソリューションを投稿していただきありがとうございます! – qed

関連する問題