allow to scroll the virtual desktop further than the desktop geometry.
[wmaker-crm.git] / util / wxcopy.c
blob003a0a55d50a57151dfa86e05455d3dac6ae0c60
1 /* wxcopy.c- copy stdin or file into cutbuffer
2 *
3 * Copyright (c) 1997-1999 Alfredo K. Kojima
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #define PROG_VERSION "wxcopy 0.3"
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <errno.h>
28 #include <X11/Xlib.h>
29 #include <X11/Xatom.h>
32 #define LINESIZE (4*1024)
33 #define MAXDATA (64*1024)
35 void
36 help(char *progn)
38 printf("Usage: %s [OPTIONS] [FILE]\n", progn);
39 puts("Copies data from FILE or stdin into X cut buffer.");
40 puts("");
41 puts(" -display <display> display to use");
42 puts(" --cutbuffer <number> cutbuffer number to put data");
43 puts(" --no-limit do not limit size of input data");
44 puts(" --clear-selection clears the current PRIMARY selection");
45 puts(" --help display this help and exit");
46 puts(" --version output version information and exit");
49 static int
50 errorHandler(Display *dpy, XErrorEvent *err)
52 /* ignore all errors */
53 return 0;
57 int
58 main(int argc, char **argv)
60 Display *dpy;
61 int i;
62 int buffer=-1;
63 char *filename=NULL;
64 FILE *file=stdin;
65 char *buf=NULL;
66 char *display_name="";
67 int l=0;
68 int buf_len = 0;
69 int limit_check = 1;
70 int clear_selection = 0;
72 for (i=1; i<argc; i++) {
73 if (argv[i][0]=='-') {
74 if (strcmp(argv[i], "--help")==0) {
75 help(argv[0]);
76 exit(0);
77 } else if (strcmp(argv[i], "--version")==0) {
78 puts(PROG_VERSION);
79 exit(0);
80 } else if (strcmp(argv[i],"-cutbuffer")==0
81 || strcmp(argv[i],"--cutbuffer")==0) {
82 if (i<argc-1) {
83 i++;
84 if (sscanf(argv[i],"%i", &buffer)!=1) {
85 fprintf(stderr, "%s: could not convert '%s' to int\n",
86 argv[0], argv[i]);
87 exit(1);
89 if (buffer<0 || buffer > 7) {
90 fprintf(stderr, "%s: invalid buffer number %i\n",
91 argv[0], buffer);
92 exit(1);
94 } else {
95 printf("%s: missing argument for '%s'\n", argv[0], argv[i]);
96 printf("Try '%s --help' for more information\n", argv[0]);
97 exit(1);
99 } else if (strcmp(argv[i], "-display")==0) {
100 if (i < argc-1) {
101 display_name = argv[++i];
102 } else {
103 printf("%s: missing argument for '%s'\n", argv[0], argv[i]);
104 printf("Try '%s --help' for more information\n", argv[0]);
105 exit(1);
107 } else if (strcmp(argv[i],"-clearselection")==0
108 || strcmp(argv[i],"--clear-selection")==0) {
109 clear_selection = 1;
110 } else if (strcmp(argv[i],"-nolimit")==0
111 || strcmp(argv[i],"--no-limit")==0) {
112 limit_check = 0;
113 } else {
114 printf("%s: invalid argument '%s'\n", argv[0], argv[i]);
115 printf("Try '%s --help' for more information\n", argv[0]);
116 exit(1);
118 } else {
119 filename = argv[i];
122 if (filename) {
123 file = fopen(filename, "r");
124 if (!file) {
125 char line[1024];
126 sprintf(line, "%s: could not open \"%s\"", argv[0], filename);
127 perror(line);
128 exit(1);
132 dpy = XOpenDisplay(display_name);
133 XSetErrorHandler(errorHandler);
134 if (!dpy) {
135 fprintf(stderr, "%s: could not open display \"%s\"\n", argv[0],
136 XDisplayName(display_name));
137 exit(1);
139 if (buffer<0) {
140 XRotateBuffers(dpy, 1);
141 buffer=0;
143 while (!feof(file)) {
144 char *nbuf;
145 char tmp[LINESIZE+2];
146 int nl=0;
149 * Use read() instead of fgets() to preserve NULs, since
150 * especially since there's no reason to read one line at a time.
152 if ((nl = fread(tmp, 1, LINESIZE, file)) <= 0) {
153 break;
155 if (buf_len == 0) {
156 nbuf = malloc(buf_len = l+nl+1);
158 else {
159 if (buf_len < l+nl+1) {
161 * To avoid terrible performance on big input buffers,
162 * grow by doubling, not by the minimum needed for the
163 * current line.
165 buf_len = 2 * buf_len + nl + 1;
166 nbuf = realloc(buf, buf_len);
168 else {
169 nbuf = buf;
172 if (!nbuf) {
173 fprintf(stderr, "%s: out of memory\n", argv[0]);
174 exit(1);
176 buf=nbuf;
178 * Don't strcat, since it would make the algorithm n-squared.
179 * Don't use strcpy, since it stops on a NUL.
181 memcpy(buf+l, tmp, nl);
182 l+=nl;
183 if (limit_check && l>=MAXDATA) {
184 fprintf
186 stderr,
187 "%s: too much data in input - more than %d bytes\n"
188 " use the -nolimit argument to remove the limit check.\n",
189 argv[0], MAXDATA
191 exit(1);
195 if (clear_selection) {
196 XSetSelectionOwner(dpy, XA_PRIMARY, None, CurrentTime);
198 if (buf) {
199 XStoreBuffer(dpy, buf, l, buffer);
201 XFlush(dpy);
202 XCloseDisplay(dpy);
203 exit(buf == NULL || errno != 0);