2 * Copyright (C) 2007 Richard Nelson <wabz@whatsbeef.net>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
22 #define PLUGIN_ID "gntclipboard"
23 #define PLUGIN_DOMAIN (g_quark_from_static_string(PLUGIN_ID))
24 #define PLUGIN_STATIC_NAME GntClipboard
28 #include <X11/Xutil.h>
29 #include <X11/Xatom.h>
32 #include <sys/types.h>
44 #include <gntplugin.h>
47 static pid_t child
= 0;
49 static gulong sig_handle
;
52 set_clip(gchar
*string
)
56 XSelectionRequestEvent
*req
;
58 Display
*dpy
= XOpenDisplay(NULL
);
62 ids
= getenv("WINDOWID");
66 XSetSelectionOwner(dpy
, XA_PRIMARY
, w
, CurrentTime
);
68 XSelectInput(dpy
, w
, StructureNotifyMask
);
70 XNextEvent(dpy
, &e
); /* this blocks. */
71 req
= &e
.xselectionrequest
;
72 if (e
.type
== SelectionRequest
) {
78 (unsigned char *)string
,
80 respond
.xselection
.property
= req
->property
;
81 respond
.xselection
.type
= SelectionNotify
;
82 respond
.xselection
.display
= req
->display
;
83 respond
.xselection
.requestor
= req
->requestor
;
84 respond
.xselection
.selection
= req
->selection
;
85 respond
.xselection
.target
= req
->target
;
86 respond
.xselection
.time
= req
->time
;
87 XSendEvent(dpy
, req
->requestor
, 0, 0, &respond
);
89 } else if (e
.type
== SelectionClear
) {
97 clipboard_changed(GntWM
*wm
, gchar
*string
)
100 kill(child
, SIGTERM
);
102 if ((child
= fork()) == 0) {
109 static FinchPluginInfo
*
110 plugin_query(GError
**error
)
112 const gchar
* const authors
[] = {
113 "Richard Nelson <wabz@whatsbeef.net>",
117 return finch_plugin_info_new(
119 "name", N_("GntClipboard"),
120 "version", DISPLAY_VERSION
,
121 "category", N_("Utility"),
122 "summary", N_("Clipboard plugin"),
123 "description", N_("When the gnt clipboard contents change, the "
124 "contents are made available to X, if possible."),
126 "website", PURPLE_WEBSITE
,
127 "abi-version", PURPLE_ABI_VERSION
,
133 plugin_load(PurplePlugin
*plugin
, GError
**error
)
136 if (!XOpenDisplay(NULL
)) {
137 purple_debug_warning("gntclipboard", "Couldn't find X display\n");
138 purple_notify_error(NULL
, _("Error"), _("Error loading the plugin."),
139 _("Couldn't find X display"), NULL
);
142 if (!getenv("WINDOWID")) {
143 purple_debug_warning("gntclipboard", "Couldn't find window\n");
144 purple_notify_error(NULL
, _("Error"), _("Error loading the plugin."),
145 _("Couldn't find window"), NULL
);
148 sig_handle
= g_signal_connect(G_OBJECT(gnt_get_clipboard()), "clipboard_changed", G_CALLBACK(clipboard_changed
), NULL
);
151 g_set_error(error
, PLUGIN_DOMAIN
, 0, _("This plugin cannot be loaded "
152 "because it was not built with X11 support."));
158 plugin_unload(PurplePlugin
*plugin
, GError
**error
)
162 kill(child
, SIGTERM
);
165 g_signal_handler_disconnect(G_OBJECT(gnt_get_clipboard()), sig_handle
);
170 PURPLE_PLUGIN_INIT(PLUGIN_STATIC_NAME
, plugin_query
, plugin_load
, plugin_unload
);