Replace functions which called once with their bodies
[pidgin-git.git] / finch / plugins / gntclipboard.c
bloba774d913926486a7b198b04c382be63282a1135c
1 /**
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
19 #include "internal.h"
20 #include <glib.h>
22 #define PLUGIN_ID "gntclipboard"
23 #define PLUGIN_DOMAIN (g_quark_from_static_string(PLUGIN_ID))
24 #define PLUGIN_STATIC_NAME GntClipboard
26 #ifdef HAVE_X11
27 #include <X11/Xlib.h>
28 #include <X11/Xutil.h>
29 #include <X11/Xatom.h>
30 #endif
32 #include <sys/types.h>
33 #include <signal.h>
35 #include <glib.h>
37 #include <plugins.h>
38 #include <version.h>
39 #include <debug.h>
40 #include <notify.h>
41 #include <gnt.h>
42 #include <gntwm.h>
44 #include <gntplugin.h>
46 #ifdef HAVE_X11
47 static pid_t child = 0;
49 static gulong sig_handle;
51 static void
52 set_clip(gchar *string)
54 Window w;
55 XEvent e, respond;
56 XSelectionRequestEvent *req;
57 const char *ids;
58 Display *dpy = XOpenDisplay(NULL);
60 if (!dpy)
61 return;
62 ids = getenv("WINDOWID");
63 if (ids == NULL)
64 return;
65 w = atoi(ids);
66 XSetSelectionOwner(dpy, XA_PRIMARY, w, CurrentTime);
67 XFlush(dpy);
68 XSelectInput(dpy, w, StructureNotifyMask);
69 while (TRUE) {
70 XNextEvent(dpy, &e); /* this blocks. */
71 req = &e.xselectionrequest;
72 if (e.type == SelectionRequest) {
73 XChangeProperty(dpy,
74 req->requestor,
75 req->property,
76 XA_STRING,
77 8, PropModeReplace,
78 (unsigned char *)string,
79 strlen(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);
88 XFlush (dpy);
89 } else if (e.type == SelectionClear) {
90 return;
93 return;
96 static void
97 clipboard_changed(GntWM *wm, gchar *string)
99 if (child) {
100 kill(child, SIGTERM);
102 if ((child = fork()) == 0) {
103 set_clip(string);
104 _exit(0);
107 #endif
109 static FinchPluginInfo *
110 plugin_query(GError **error)
112 const gchar * const authors[] = {
113 "Richard Nelson <wabz@whatsbeef.net>",
114 NULL
117 return finch_plugin_info_new(
118 "id", PLUGIN_ID,
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."),
125 "authors", authors,
126 "website", PURPLE_WEBSITE,
127 "abi-version", PURPLE_ABI_VERSION,
128 NULL
132 static gboolean
133 plugin_load(PurplePlugin *plugin, GError **error)
135 #ifdef HAVE_X11
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);
140 return FALSE;
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);
146 return FALSE;
148 sig_handle = g_signal_connect(G_OBJECT(gnt_get_clipboard()), "clipboard_changed", G_CALLBACK(clipboard_changed), NULL);
149 return TRUE;
150 #else
151 g_set_error(error, PLUGIN_DOMAIN, 0, _("This plugin cannot be loaded "
152 "because it was not built with X11 support."));
153 return FALSE;
154 #endif
157 static gboolean
158 plugin_unload(PurplePlugin *plugin, GError **error)
160 #ifdef HAVE_X11
161 if (child) {
162 kill(child, SIGTERM);
163 child = 0;
165 g_signal_handler_disconnect(G_OBJECT(gnt_get_clipboard()), sig_handle);
166 #endif
167 return TRUE;
170 PURPLE_PLUGIN_INIT(PLUGIN_STATIC_NAME, plugin_query, plugin_load, plugin_unload);