1 /*
2 * autocutsel by Michael Witrant <mike @ lepton . fr>
3 * Manipulates the cutbuffer and the selection
4 * Copyright (c) 2001-2006 Michael Witrant.
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 * This program is distributed under the terms
21 * of the GNU General Public License (read the COPYING file)
22 *
23 */
24
25
26 #include "common.h"
27
28 static XrmOptionDescRec optionDesc[] = {
29 {"-selection", "selection", XrmoptionSepArg, NULL},
30 {"-select", "selection", XrmoptionSepArg, NULL},
31 {"-sel", "selection", XrmoptionSepArg, NULL},
32 {"-s", "selection", XrmoptionSepArg, NULL},
33 {"-cutbuffer", "cutBuffer", XrmoptionSepArg, NULL},
34 {"-cut", "cutBuffer", XrmoptionSepArg, NULL},
35 {"-c", "cutBuffer", XrmoptionSepArg, NULL},
36 {"-debug", "debug", XrmoptionNoArg, "on"},
37 {"-d", "debug", XrmoptionNoArg, "on"},
38 {"-verbose", "verbose", XrmoptionNoArg, "on"},
39 {"-v", "verbose", XrmoptionNoArg, "on"},
40 };
41
Syntax(char * call)42 int Syntax(char *call)
43 {
44 fprintf (stderr,
45 "usage: %s [-selection <name>] [-cutbuffer <number>] [-debug] [-verbose] cut|sel [<value>]\n",
46 call);
47 fprintf (stderr,
48 " %s [-selection <name>] [-cutbuffer <number>] [-debug] [-verbose] targets\n",
49 call);
50 fprintf (stderr,
51 " %s [-selection <name>] [-cutbuffer <number>] [-debug] [-verbose] length\n",
52 call);
53 exit (1);
54 }
55
56 #define Offset(field) XtOffsetOf(OptionsRec, field)
57
58 static XtResource resources[] = {
59 {"selection", "Selection", XtRString, sizeof(String),
60 Offset(selection_name), XtRString, "CLIPBOARD"},
61 {"cutBuffer", "CutBuffer", XtRInt, sizeof(int),
62 Offset(buffer), XtRImmediate, (XtPointer)0},
63 {"debug", "Debug", XtRString, sizeof(String),
64 Offset(debug_option), XtRString, "off"},
65 {"verbose", "Verbose", XtRString, sizeof(String),
66 Offset(verbose_option), XtRString, "off"},
67 };
68
69 #undef Offset
70
71 // Called when we no longer own the selection
LoseSelection(Widget w,Atom * selection)72 static void LoseSelection(Widget w, Atom *selection)
73 {
74 if (options.debug)
75 printf("Selection lost\n");
76 exit(0);
77 }
78
PrintSelection(Widget w,XtPointer client_data,Atom * selection,Atom * type,XtPointer value,unsigned long * received_length,int * format)79 static void PrintSelection(Widget w, XtPointer client_data, Atom *selection,
80 Atom *type, XtPointer value,
81 unsigned long *received_length, int *format)
82 {
83 Display* d = XtDisplay(w);
84
85 if (*type == 0)
86 printf("Nobody owns the selection\n");
87 else if (*type == XA_STRING)
88 printf("%s\n", (char*)value);
89 else
90 printf("Invalid type received: %s\n", XGetAtomName(d, *type));
91
92 XtFree(value);
93 exit(0);
94 }
95
TargetsReceived(Widget w,XtPointer client_data,Atom * selection,Atom * type,XtPointer value,unsigned long * length,int * format)96 static void TargetsReceived(Widget w, XtPointer client_data, Atom *selection,
97 Atom *type, XtPointer value,
98 unsigned long *length, int *format)
99 {
100 Display* d = XtDisplay(w);
101 int i;
102 Atom *atoms;
103
104 if (*type == 0)
105 printf("No target received\n");
106 else if (*type == XA_ATOM) {
107 atoms = (Atom*)value;
108 printf("%lu targets (%i bits each):\n", *length, *format);
109 for (i=0; i<*length; i++)
110 printf("%s\n", XGetAtomName(d, atoms[i]));
111 } else
112 printf("Invalid type received: %s\n", XGetAtomName(d, *type));
113
114 XtFree(value);
115 exit(0);
116 }
117
LengthReceived(Widget w,XtPointer client_data,Atom * selection,Atom * type,XtPointer value,unsigned long * received_length,int * format)118 static void LengthReceived(Widget w, XtPointer client_data, Atom *selection,
119 Atom *type, XtPointer value,
120 unsigned long *received_length, int *format)
121 {
122 Display* d = XtDisplay(w);
123
124 if (*type == 0)
125 printf("No length received\n");
126 else if (*type == XA_INTEGER) {
127 printf("Length is %" PRIx32 "\n", *(CARD32*)value);
128 } else
129 printf("Invalid type received: %s\n", XGetAtomName(d, *type));
130
131 XtFree(value);
132 exit(0);
133 }
134
OwnSelection(XtPointer p,XtIntervalId * i)135 void OwnSelection(XtPointer p, XtIntervalId* i)
136 {
137 if (XtOwnSelection(box, options.selection,
138 0, //XtLastTimestampProcessed(dpy),
139 ConvertSelection, LoseSelection, NULL) == True) {
140 if (options.debug)
141 printf("Selection owned\n");
142 } else
143 printf("WARNING: Unable to own selection!\n");
144 }
145
GetSelection(XtPointer p,XtIntervalId * i)146 void GetSelection(XtPointer p, XtIntervalId* i)
147 {
148 XtGetSelectionValue(box, selection, XA_STRING,
149 PrintSelection, NULL,
150 CurrentTime);
151 }
152
GetTargets(XtPointer p,XtIntervalId * i)153 void GetTargets(XtPointer p, XtIntervalId* i)
154 {
155 Display* d = XtDisplay(box);
156 XtGetSelectionValue(box, selection, XA_TARGETS(d),
157 TargetsReceived, NULL,
158 CurrentTime);
159 }
160
GetLength(XtPointer p,XtIntervalId * i)161 void GetLength(XtPointer p, XtIntervalId* i)
162 {
163 Display* d = XtDisplay(box);
164 XtGetSelectionValue(box, selection, XA_LENGTH(d),
165 LengthReceived, NULL,
166 CurrentTime);
167 }
168
Exit(XtPointer p,XtIntervalId * i)169 void Exit(XtPointer p, XtIntervalId* i)
170 {
171 exit(0);
172 }
173
main(int argc,char * argv[])174 int main(int argc, char* argv[])
175 {
176 Widget top;
177 top = XtVaAppInitialize(&context, "CutSel",
178 optionDesc, XtNumber(optionDesc), &argc, argv, NULL,
179 XtNoverrideRedirect, True,
180 XtNgeometry, "-10-10",
181 NULL);
182
183 if (argc < 2) Syntax(argv[0]);
184
185 XtGetApplicationResources(top, (XtPointer)&options,
186 resources, XtNumber(resources),
187 NULL, ZERO );
188
189
190 if (strcmp(options.debug_option, "on") == 0)
191 options.debug = 1;
192 else
193 options.debug = 0;
194
195 if (strcmp(options.verbose_option, "on") == 0)
196 options.verbose = 1;
197 else
198 options.verbose = 0;
199
200 if (options.debug || options.verbose)
201 printf("cutsel v%s\n", VERSION);
202
203 options.value = NULL;
204 options.length = 0;
205
206 box = XtCreateManagedWidget("box", boxWidgetClass, top, NULL, 0);
207 dpy = XtDisplay(top);
208
209 selection = XInternAtom(dpy, options.selection_name, 0);
210 options.selection = selection;
211 buffer = 0;
212
213 if (strcmp(argv[1], "cut") == 0) {
214 if (argc > 2) {
215 XStoreBuffer(dpy,
216 argv[2],
217 strlen(argv[2]),
218 buffer);
219 XtAppAddTimeOut(context, 10, Exit, 0);
220 } else {
221 options.value = XFetchBuffer(dpy, &options.length, buffer);
222 if (options.length)
223 printf("%s\n", options.value);
224 exit(0);
225 }
226 } else if (strcmp(argv[1], "sel") == 0) {
227 if (argc > 2) {
228 options.value = argv[2];
229 options.length = strlen(argv[2]);
230 XtAppAddTimeOut(context, 10, OwnSelection, 0);
231 } else {
232 XtAppAddTimeOut(context, 10, GetSelection, 0);
233 }
234 } else if (strcmp(argv[1], "targets") == 0) {
235 XtAppAddTimeOut(context, 10, GetTargets, 0);
236 } else if (strcmp(argv[1], "length") == 0) {
237 XtAppAddTimeOut(context, 10, GetLength, 0);
238 } else {
239 Syntax(argv[0]);
240 }
241
242 XtRealizeWidget(top);
243 XtAppMainLoop(context);
244 return 0;
245 }
246