/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ /************************************************ rbgtkclipboard.c - $Author: ggc $ $Date: 2007/07/13 14:27:09 $ Copyright (C) 2004,2006 Ruby-GNOME2 Project Copyright (C) 2002,2003 OGASAWARA, Takeshi ************************************************/ #include "global.h" #define _SELF(s) RVAL2CLIPBOARD(s) #ifndef GTK_TYPE_CLIPBOARD static GtkClipboard* clipboard_copy(const GtkClipboard *clipboard) { /* I don't know how to copy this object ... */ return (GtkClipboard*)clipboard; } GType rbgtk_clipboard_get_type() { static GType our_type = 0; if(our_type == 0) our_type = g_boxed_type_register_static("GtkClipboard", (GBoxedCopyFunc)clipboard_copy, (GBoxedFreeFunc)g_free); return our_type; } GtkClipboard* rbgtk_get_clipboard(VALUE obj) { return GTK_CLIPBOARD(RVAL2GOBJ(obj)); } VALUE rbgtk_make_clipboard(GtkClipboard *gobj) { return GOBJ2RVAL(gobj); } #endif static VALUE clipboard_get(int argc, VALUE *argv, VALUE self) { GtkClipboard *clipboard; if (argc == 1){ VALUE selection; rb_scan_args(argc, argv, "10", &selection); clipboard = gtk_clipboard_get(RVAL2ATOM(selection)); } else { #if GTK_CHECK_VERSION(2,2,0) VALUE display, selection; rb_scan_args(argc, argv, "20", &display, &selection); clipboard = gtk_clipboard_get_for_display(GDK_DISPLAY_OBJECT(RVAL2GOBJ(display)), RVAL2ATOM(selection)); #else rb_raise(rb_eArgError, "Wrong number of arguments: %d", argc); #endif } return CLIPBOARD2RVAL(clipboard); } static VALUE clipboard_get_display(VALUE self) { #if GTK_CHECK_VERSION(2,2,0) return GOBJ2RVAL(gtk_clipboard_get_display(_SELF(self))); #else return Qnil; #endif } static void clipboard_get_func(GtkClipboard *clipboard, GtkSelectionData *selection_data, guint info, gpointer func) { rb_funcall((VALUE)func, id_call, 2, CLIPBOARD2RVAL(clipboard), BOXED2RVAL(selection_data, GTK_TYPE_SELECTION_DATA)); } static VALUE clipboard_set(VALUE self, VALUE targets) { const GtkTargetEntry* gtargets = (const GtkTargetEntry*)rbgtk_get_target_entry(targets); VALUE func = rb_block_proc(); G_RELATIVE(self, func); return CBOOL2RVAL(gtk_clipboard_set_with_data(_SELF(self), gtargets, RARRAY_LEN(targets), (GtkClipboardGetFunc)clipboard_get_func, (GtkClipboardClearFunc)NULL, (gpointer)func)); } /* Do not implement this. Use Gtk::Clipboard#set_with_data instead. gboolean gtk_clipboard_set_with_owner (GtkClipboard *clipboard, const GtkTargetEntry *targets, guint n_targets, GtkClipboardGetFunc get_func, GtkClipboardClearFunc clear_func, GObject *owner); static VALUE clipboard_get_owner(VALUE self) { GObject *gobj; gobj = gtk_clipboard_get_owner(_SELF(self)); return gobj ? GOBJ2RVAL(gobj) : Qnil; } */ static VALUE clipboard_clear(VALUE self) { gtk_clipboard_clear(_SELF(self)); return self; } static VALUE clipboard_set_text(VALUE self, VALUE text) { StringValue(text); gtk_clipboard_set_text(_SELF(self), RVAL2CSTR(text), RSTRING_LEN(text)); return self; } #if GTK_CHECK_VERSION(2,6,0) static VALUE clipboard_set_image(VALUE self, VALUE pixbuf) { gtk_clipboard_set_image(_SELF(self), GDK_PIXBUF(RVAL2GOBJ(pixbuf))); return self; } #endif static void clipboard_received_func(GtkClipboard *clipboard, GtkSelectionData *selection_data, gpointer func) { rb_funcall((VALUE)func, id_call, 2, CLIPBOARD2RVAL(clipboard), BOXED2RVAL(selection_data, GTK_TYPE_SELECTION_DATA)); } static VALUE clipboard_request_contents(VALUE self, VALUE target) { VALUE func = rb_block_proc(); G_RELATIVE(self, func); gtk_clipboard_request_contents(_SELF(self), RVAL2ATOM(target), (GtkClipboardReceivedFunc)clipboard_received_func, (gpointer)func); return self; } static void clipboard_text_received_func(GtkClipboard *clipboard, const gchar *text, gpointer func) { VALUE vtext = Qnil; if (text) { vtext = CSTR2RVAL(text); } rb_funcall((VALUE)func, id_call, 2, CLIPBOARD2RVAL(clipboard), vtext); } static VALUE clipboard_request_text(VALUE self) { VALUE func = rb_block_proc(); G_RELATIVE(self, func); gtk_clipboard_request_text(_SELF(self), (GtkClipboardTextReceivedFunc)clipboard_text_received_func, (gpointer)func); return self; } #if GTK_CHECK_VERSION(2,6,0) static void clipboard_image_received_func(GtkClipboard *clipboard, GdkPixbuf *pixbuf, gpointer func) { rb_funcall((VALUE)func, id_call, 2, CLIPBOARD2RVAL(clipboard), GOBJ2RVAL(pixbuf)); } static VALUE clipboard_request_image(VALUE self) { VALUE func = rb_block_proc(); G_RELATIVE(self, func); gtk_clipboard_request_image(_SELF(self), (GtkClipboardImageReceivedFunc)clipboard_image_received_func, (gpointer)func); return self; } #endif #if GTK_CHECK_VERSION(2,4,0) static void clipboard_target_received_func(GtkClipboard *clipboard, GdkAtom *atoms, gint n_atoms, gpointer func) { gint i; VALUE ary = rb_ary_new(); for (i = 0; i < n_atoms; i++){ rb_ary_push(ary, BOXED2RVAL(atoms[i], GDK_TYPE_ATOM)); } rb_funcall((VALUE)func, id_call, 2, CLIPBOARD2RVAL(clipboard), ary); } static VALUE clipboard_request_targets(VALUE self) { VALUE func = rb_block_proc(); G_RELATIVE(self, func); gtk_clipboard_request_targets(_SELF(self), (GtkClipboardTargetsReceivedFunc)clipboard_target_received_func, (gpointer)func); return self; } #endif #if GTK_CHECK_VERSION(2,10,0) static void clipboard_rich_text_received_func(GtkClipboard *clipboard, GdkAtom format, const guint8 *text, gsize length, gpointer func) { rb_funcall((VALUE)func, id_call, 3, CLIPBOARD2RVAL(clipboard), BOXED2RVAL(format, GDK_TYPE_ATOM), rb_str_new((char*)text, length)); } static VALUE clipboard_request_rich_text(VALUE self, VALUE buffer) { VALUE func = rb_block_proc(); G_RELATIVE(self, func); gtk_clipboard_request_rich_text(_SELF(self), GTK_TEXT_BUFFER(RVAL2GOBJ(buffer)), (GtkClipboardRichTextReceivedFunc)clipboard_rich_text_received_func, (gpointer)func); return self; } #endif static VALUE clipboard_wait_for_contents(VALUE self, VALUE target) { return BOXED2RVAL(gtk_clipboard_wait_for_contents( _SELF(self), RVAL2ATOM(target)), GTK_TYPE_SELECTION_DATA); } static VALUE clipboard_wait_for_text(VALUE self) { gchar *str; str = gtk_clipboard_wait_for_text(_SELF(self)); return str ? CSTR2RVAL(str) : Qnil; } #if GTK_CHECK_VERSION(2,6,0) static VALUE clipboard_wait_for_image(VALUE self) { GdkPixbuf* pixbuf = gtk_clipboard_wait_for_image(_SELF(self)); return GOBJ2RVAL(pixbuf); } #endif #if GTK_CHECK_VERSION(2,10,0) static VALUE clipboard_wait_for_rich_text(VALUE self, VALUE buffer) { GdkAtom format; gsize length; guint8* data = gtk_clipboard_wait_for_rich_text(_SELF(self), GTK_TEXT_BUFFER(RVAL2GOBJ(buffer)), &format, &length); if (data){ VALUE str = rb_str_new((char*)data, length); g_free(data); return rb_assoc_new(str, BOXED2RVAL(format, GDK_TYPE_ATOM)); } else { return rb_assoc_new(Qnil, BOXED2RVAL(format, GDK_TYPE_ATOM)); } } #endif static VALUE clipboard_wait_is_text_available(VALUE self) { return CBOOL2RVAL(gtk_clipboard_wait_is_text_available(_SELF(self))); } #if GTK_CHECK_VERSION(2,6,0) static VALUE clipboard_wait_is_image_available(VALUE self) { return CBOOL2RVAL(gtk_clipboard_wait_is_image_available(_SELF(self))); } #endif #if GTK_CHECK_VERSION(2,10,0) static VALUE clipboard_wait_is_rich_text_available(VALUE self, VALUE buffer) { return CBOOL2RVAL(gtk_clipboard_wait_is_rich_text_available(_SELF(self), GTK_TEXT_BUFFER(RVAL2GOBJ(buffer)))); } #endif #if GTK_CHECK_VERSION(2,4,0) static VALUE clipboard_wait_for_targets(VALUE self) { gint i; VALUE ary = Qnil; GdkAtom* targets; gint n_targets = 0; gboolean ret = gtk_clipboard_wait_for_targets(_SELF(self), &targets, &n_targets); if (ret){ ary = rb_ary_new(); for (i = 0; i < n_targets; i++){ if ((GdkAtom)targets == (GdkAtom)GDK_NONE){ rb_ary_push(ary, rb_eval_string("Gdk::Atom::NONE")); } else rb_ary_push(ary, BOXED2RVAL(targets, GDK_TYPE_ATOM)); targets++; } /* How can I this ? g_free(&o_targets); */ } return ary; } #endif #if GTK_CHECK_VERSION(2,6,0) static VALUE clipboard_wait_is_target_available(VALUE self, VALUE target) { return CBOOL2RVAL(gtk_clipboard_wait_is_target_available(_SELF(self), RVAL2ATOM(target))); } static VALUE clipboard_set_can_store(VALUE self, VALUE targets) { gint n_targets = 0; GtkTargetEntry* entries = (GtkTargetEntry*)NULL; if (!NIL_P(targets)){ n_targets = RARRAY_LEN(targets); entries = rbgtk_get_target_entry(targets); } gtk_clipboard_set_can_store(_SELF(self), entries, n_targets); return self; } static VALUE clipboard_store(VALUE self) { gtk_clipboard_store(_SELF(self)); return self; } #endif void Init_gtk_clipboard() { VALUE gClipboard = G_DEF_CLASS(GTK_TYPE_CLIPBOARD, "Clipboard", mGtk); rb_define_singleton_method(gClipboard, "get", clipboard_get, -1); rb_define_method(gClipboard, "display", clipboard_get_display, 0); rb_define_method(gClipboard, "set", clipboard_set, 1); /* rb_define_method(gClipboard, "owner", clipboard_get_owner, 0); */ rb_define_method(gClipboard, "clear", clipboard_clear, 0); rb_define_method(gClipboard, "set_text", clipboard_set_text, 1); #if GTK_CHECK_VERSION(2,6,0) rb_define_method(gClipboard, "set_image", clipboard_set_image, 1); #endif rb_define_method(gClipboard, "request_contents", clipboard_request_contents, 1); rb_define_method(gClipboard, "request_text", clipboard_request_text, 0); #if GTK_CHECK_VERSION(2,6,0) rb_define_method(gClipboard, "request_image", clipboard_request_image, 0); #endif #if GTK_CHECK_VERSION(2,4,0) rb_define_method(gClipboard, "request_targets", clipboard_request_targets, 0); #endif #if GTK_CHECK_VERSION(2,10,0) rb_define_method(gClipboard, "request_rich_text", clipboard_request_rich_text, 1); #endif rb_define_method(gClipboard, "wait_for_contents", clipboard_wait_for_contents, 1); rb_define_method(gClipboard, "wait_for_text", clipboard_wait_for_text, 0); #if GTK_CHECK_VERSION(2,6,0) rb_define_method(gClipboard, "wait_for_image", clipboard_wait_for_image, 0); #endif #if GTK_CHECK_VERSION(2,10,0) rb_define_method(gClipboard, "wait_for_rich_text", clipboard_wait_for_rich_text, 1); #endif rb_define_method(gClipboard, "wait_is_text_available?", clipboard_wait_is_text_available, 0); #if GTK_CHECK_VERSION(2,6,0) rb_define_method(gClipboard, "wait_is_image_available?", clipboard_wait_is_image_available, 0); #endif #if GTK_CHECK_VERSION(2,10,0) rb_define_method(gClipboard, "wait_is_rich_text_available?", clipboard_wait_is_rich_text_available, 1); #endif #if GTK_CHECK_VERSION(2,4,0) rb_define_method(gClipboard, "wait_for_targets", clipboard_wait_for_targets, 0); #endif #if GTK_CHECK_VERSION(2,6,0) rb_define_method(gClipboard, "wait_is_target_available?", clipboard_wait_is_target_available, 1); rb_define_method(gClipboard, "set_can_store", clipboard_set_can_store, 1); rb_define_method(gClipboard, "store", clipboard_store, 0); #endif G_DEF_SETTERS(gClipboard); }