~profzoom/ubuntu/quantal/wmaker/bug-1079925

« back to all changes in this revision

Viewing changes to util/wxcopy.c

  • Committer: Bazaar Package Importer
  • Author(s): Marcelo E. Magallon
  • Date: 2004-11-10 14:05:30 UTC
  • Revision ID: james.westby@ubuntu.com-20041110140530-qpd66b5lm38x7apk
Tags: upstream-0.91.0
ImportĀ upstreamĀ versionĀ 0.91.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* wxcopy.c- copy stdin or file into cutbuffer
 
2
 *
 
3
 *  Copyright (c) 1997-2003 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.
 
9
 *
 
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.
 
14
 *
 
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.
 
18
 */
 
19
 
 
20
#define PROG_VERSION "wxcopy 0.3"
 
21
 
 
22
 
 
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>
 
30
 
 
31
 
 
32
#define LINESIZE        (4*1024)
 
33
#define MAXDATA         (64*1024)
 
34
 
 
35
void
 
36
help(char *progn)
 
37
{
 
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");
 
47
}
 
48
 
 
49
static int
 
50
errorHandler(Display *dpy, XErrorEvent *err)
 
51
{
 
52
    /* ignore all errors */
 
53
    return 0;
 
54
}
 
55
 
 
56
 
 
57
int
 
58
main(int argc, char **argv)
 
59
{
 
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;
 
71
 
 
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);
 
88
                    }
 
89
                    if (buffer<0 || buffer > 7) {
 
90
                        fprintf(stderr, "%s: invalid buffer number %i\n",
 
91
                                argv[0], buffer);
 
92
                        exit(1);
 
93
                    }
 
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);
 
98
                }
 
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);
 
106
                }
 
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);
 
117
            }
 
118
        } else {
 
119
            filename = argv[i];
 
120
        }
 
121
    }
 
122
    if (filename) {
 
123
        file = fopen(filename, "rb");
 
124
        if (!file) {
 
125
            char line[1024];
 
126
            sprintf(line, "%s: could not open \"%s\"", argv[0], filename);
 
127
            perror(line);
 
128
            exit(1);
 
129
        }
 
130
    }
 
131
 
 
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);
 
138
    }
 
139
 
 
140
    if (buffer<0) {
 
141
        Atom *rootWinProps;
 
142
        int exists[8] = {0, 0, 0, 0, 0, 0, 0, 0};
 
143
        int i, count;
 
144
 
 
145
        /* Create missing CUT_BUFFERs */
 
146
        rootWinProps = XListProperties(dpy, DefaultRootWindow(dpy), &count);
 
147
        for (i=0; i<count; i++) {
 
148
            switch(rootWinProps[i]) {
 
149
            case XA_CUT_BUFFER0:
 
150
                exists[0] = 1; break;
 
151
            case XA_CUT_BUFFER1:
 
152
                exists[1] = 1; break;
 
153
            case XA_CUT_BUFFER2:
 
154
                exists[2] = 1; break;
 
155
            case XA_CUT_BUFFER3:
 
156
                exists[3] = 1; break;
 
157
            case XA_CUT_BUFFER4:
 
158
                exists[4] = 1; break;
 
159
            case XA_CUT_BUFFER5:
 
160
                exists[5] = 1; break;
 
161
            case XA_CUT_BUFFER6:
 
162
                exists[6] = 1; break;
 
163
            case XA_CUT_BUFFER7:
 
164
                exists[7] = 1; break;
 
165
            default:
 
166
                break;
 
167
            }
 
168
        }
 
169
        if (rootWinProps) {
 
170
            XFree(rootWinProps);
 
171
        }
 
172
        for (i=0; i<8; i++) {
 
173
            if (!exists[i]) {
 
174
                XStoreBuffer(dpy, "", 0, i);
 
175
            }
 
176
        }
 
177
 
 
178
        XRotateBuffers(dpy, 1);
 
179
        buffer=0;
 
180
    }
 
181
 
 
182
    while (!feof(file)) {
 
183
        char *nbuf;
 
184
        char tmp[LINESIZE+2];
 
185
        int nl=0;
 
186
 
 
187
        /*
 
188
         * Use read() instead of fgets() to preserve NULLs, since
 
189
         * especially since there's no reason to read one line at a time.
 
190
         */
 
191
        if ((nl = fread(tmp, 1, LINESIZE, file)) <= 0) {
 
192
            break;
 
193
        }
 
194
        if (buf_len == 0) {
 
195
            nbuf = malloc(buf_len = l+nl+1);
 
196
        } else if (buf_len < l+nl+1) {
 
197
            /*
 
198
             * To avoid terrible performance on big input buffers,
 
199
             * grow by doubling, not by the minimum needed for the
 
200
             * current line.
 
201
             */
 
202
            buf_len = 2 * buf_len + nl + 1;
 
203
            /* some realloc implementations don't do malloc if buf==NULL */
 
204
            if (buf == NULL) {
 
205
                nbuf = malloc(buf_len);
 
206
            } else {
 
207
                nbuf = realloc(buf, buf_len);
 
208
            }
 
209
        } else {
 
210
            nbuf = buf;
 
211
        }
 
212
        if (!nbuf) {
 
213
            fprintf(stderr, "%s: out of memory\n", argv[0]);
 
214
            exit(1);
 
215
        }
 
216
        buf=nbuf;
 
217
        /*
 
218
         * Don't strcat, since it would make the algorithm n-squared.
 
219
         * Don't use strcpy, since it stops on a NUL.
 
220
         */
 
221
        memcpy(buf+l, tmp, nl);
 
222
        l+=nl;
 
223
        if (limit_check && l>=MAXDATA) {
 
224
            fprintf
 
225
                (
 
226
                 stderr,
 
227
                 "%s: too much data in input - more than %d bytes\n"
 
228
                 "  use the -nolimit argument to remove the limit check.\n",
 
229
                 argv[0], MAXDATA
 
230
                );
 
231
            exit(1);
 
232
        }
 
233
    }
 
234
 
 
235
    if (clear_selection) {
 
236
        XSetSelectionOwner(dpy, XA_PRIMARY, None, CurrentTime);
 
237
    }
 
238
    if (buf) {
 
239
        XStoreBuffer(dpy, buf, l, buffer);
 
240
    }
 
241
    XFlush(dpy);
 
242
    XCloseDisplay(dpy);
 
243
    exit(buf == NULL || errno != 0);
 
244
}
 
245