comparison console/plugins/gntclipboard.c @ 15750:0eb7846f9e7e

Add a gntclipboard. You can select text in a textview with the mouse, and paste it in an entry with ctrl-v (or rebind GntEntry's clipboard-paste). If you use the s.so WM, pressing alt-shift-c ("toggle-clipboard") will toggle display of the clipboard contents in a possibly easy-to-copy-with-the-x-mouse window. This includes a plugin which interacts with the X selection, which is not built by default.
author Richard Nelson <wabz@pidgin.im>
date Fri, 02 Mar 2007 01:48:11 +0000
parents
children 8afc77eb6c1f
comparison
equal deleted inserted replaced
15749:f403bc58ba07 15750:0eb7846f9e7e
1 /**
2 * @file gntclipboard.c
3 *
4 * Copyright (C) 2007 Richard Nelson <wabz@whatsbeef.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21
22 #include "internal.h"
23 #include <glib.h>
24
25 #define PLUGIN_STATIC_NAME "GntClipboard"
26
27 #ifdef HAVE_X11
28 #include <X11/Xlib.h>
29 #include <X11/Xutil.h>
30 #include <X11/Xatom.h>
31 #endif
32
33 #include <glib.h>
34
35 #include <plugin.h>
36 #include <version.h>
37 #include <debug.h>
38 #include <gntwm.h>
39
40 #include <gntplugin.h>
41
42 static gboolean stop = FALSE;
43
44 static gulong sig_handle;
45
46 static gpointer *
47 set_clip(gchar *string)
48 {
49 #ifdef HAVE_X11
50 Window w;
51 XEvent e, respond;
52 XSelectionRequestEvent *req;
53 const char *ids;
54 Display *dpy = XOpenDisplay(NULL);
55
56 if (!dpy)
57 return NULL;
58 ids = getenv("WINDOWID");
59 if (ids == NULL)
60 return NULL;
61 w = atoi(ids);
62 XSetSelectionOwner(dpy, XA_PRIMARY, w, CurrentTime);
63 XFlush(dpy);
64 XSelectInput(dpy, w, StructureNotifyMask);
65 while (!stop) {
66 XNextEvent(dpy, &e);
67 req = &e.xselectionrequest;
68 if (e.type == SelectionRequest) {
69 XChangeProperty(dpy,
70 req->requestor,
71 req->property,
72 XA_STRING,
73 8, PropModeReplace,
74 (unsigned char *)string,
75 strlen(string));
76 respond.xselection.property = req->property;
77 respond.xselection.type = SelectionNotify;
78 respond.xselection.display = req->display;
79 respond.xselection.requestor = req->requestor;
80 respond.xselection.selection = req->selection;
81 respond.xselection.target= req->target;
82 respond.xselection.time = req->time;
83 XSendEvent(dpy, req->requestor, 0, 0, &respond);
84 XFlush (dpy);
85 } else if (e.type == SelectionClear) {
86 return NULL;
87 }
88 }
89 #endif
90 return NULL;
91 }
92
93 static void
94 clipboard_changed(GntWM *wm, gchar *string)
95 {
96 #ifdef HAVE_X11
97 static GThread *thread = NULL;
98 if (thread) {
99 stop = TRUE;
100 thread = g_thread_join(thread);
101 }
102 g_thread_create((GThreadFunc)set_clip, string, TRUE, NULL);
103 #endif
104 }
105
106 static gboolean
107 plugin_load(GaimPlugin *plugin)
108 {
109 if (!XOpenDisplay(NULL))
110 gaim_debug_warning("gntclipboard", "Couldn't find X display\n");
111 if (!getenv("WINDOWID"))
112 gaim_debug_warning("gntclipboard", "Couldn't find window\n");
113 sig_handle = g_signal_connect(G_OBJECT(gnt_get_clipboard()), "clipboard_changed", G_CALLBACK(clipboard_changed), NULL);
114 return TRUE;
115 }
116
117 static gboolean
118 plugin_unload(GaimPlugin *plugin)
119 {
120 g_signal_handler_disconnect(G_OBJECT(gnt_get_clipboard()), sig_handle);
121 return TRUE;
122 }
123
124 static GaimPluginInfo info =
125 {
126 GAIM_PLUGIN_MAGIC,
127 GAIM_MAJOR_VERSION,
128 GAIM_MINOR_VERSION,
129 GAIM_PLUGIN_STANDARD,
130 GAIM_GNT_PLUGIN_TYPE,
131 0,
132 NULL,
133 GAIM_PRIORITY_DEFAULT,
134 "gntclipboard",
135 N_("GntClipboard"),
136 VERSION,
137 N_("Clipboard plugin"),
138 N_("When the gnt clipboard contents change, "
139 "the contents are made available to X, if possible."),
140 "Richard Nelson <wabz@whatsbeef.net>",
141 "http://gaim.sourceforge.net",
142 plugin_load,
143 plugin_unload,
144 NULL,
145 NULL,
146 NULL,
147 NULL,
148 NULL
149 };
150
151 static void
152 init_plugin(GaimPlugin *plugin)
153 {
154 g_thread_init(NULL);
155 }
156
157 GAIM_INIT_PLUGIN(PLUGIN_STATIC_NAME, init_plugin, info)