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

« back to all changes in this revision

Viewing changes to util/wxpaste.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
/* wxpaste.c- paste contents of cutbuffer to stdout
 
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 "wxpaste (Window Maker) 0.3"
 
21
 
 
22
#include "../src/config.h"
 
23
 
 
24
#include <stdio.h>
 
25
#include <stdlib.h>
 
26
#include <unistd.h>
 
27
#include <string.h>
 
28
#include <errno.h>
 
29
#include <X11/Xlib.h>
 
30
#include <X11/Xatom.h>
 
31
#include <sys/time.h>
 
32
#include <sys/types.h>
 
33
#ifdef HAVE_SYS_SELECT_H
 
34
# include <sys/select.h>
 
35
#endif
 
36
 
 
37
 
 
38
#define MAXDATA         (4*1024*1024)
 
39
 
 
40
 
 
41
void
 
42
help(char *progn)
 
43
{
 
44
    printf("Usage: %s [OPTIONS] [FILE]\n", progn);
 
45
    puts("Copies data from X selection or cutbuffer to FILE or stdout.");
 
46
    puts("");
 
47
    puts("  -display display            display to use");
 
48
    puts("  --cutbuffer number          cutbuffer number to get data from");
 
49
    puts("  --selection [selection]     reads data from named selection instead of\n"
 
50
         "                              cutbuffer");
 
51
    puts("  --help                      display this help and exit");
 
52
    puts("  --version                   output version information and exit");
 
53
}
 
54
 
 
55
 
 
56
Time
 
57
getTimestamp(Display *dpy, Window win)
 
58
{
 
59
    XEvent ev;
 
60
 
 
61
    /* So we do this trickery to get a time stamp:
 
62
     *
 
63
     * 1. Grab the server because we are paranoid and don't want to
 
64
     * get in a race with another instance of wxpaste being ran at the
 
65
     * same time.
 
66
     *
 
67
     * 2. Set a dummy property in our window.
 
68
     *
 
69
     * 3. Get the PropertyNotify event and get it's timestamp.
 
70
     *
 
71
     * 4. Ungrab the server.
 
72
     */
 
73
 
 
74
    XSelectInput(dpy, win, PropertyChangeMask);
 
75
 
 
76
    /* Generate a PropertyNotify event */
 
77
    XStoreName(dpy, win, "shit");
 
78
 
 
79
    /* wait for the event */
 
80
    while (1) {
 
81
        XNextEvent(dpy, &ev);
 
82
        if (ev.type == PropertyNotify)
 
83
            break;
 
84
    }
 
85
 
 
86
    return ev.xproperty.time;
 
87
}
 
88
 
 
89
 
 
90
char*
 
91
fetchSelection(Display *dpy, char *selection, char *progName)
 
92
{
 
93
    Atom selatom = XInternAtom(dpy, selection, False);
 
94
    Atom clipatom = XInternAtom(dpy, "CLIPBOARD", False);
 
95
    Time now;
 
96
    XEvent ev;
 
97
    Window win;
 
98
    int ok = 0;
 
99
    struct timeval timeout;
 
100
    fd_set fdset;
 
101
 
 
102
    win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 1, 1,
 
103
                              0, 0, 0);
 
104
    /*
 
105
     * The ICCCM says that we can't pass CurrentTime as the timestamp
 
106
     * for XConvertSelection(), but we don't have anything to use as
 
107
     * a timestamp...
 
108
     */
 
109
    now = getTimestamp(dpy, win);
 
110
 
 
111
    XConvertSelection(dpy, selatom, XA_STRING, clipatom, win, now);
 
112
 
 
113
    timeout.tv_sec = 1;
 
114
    timeout.tv_usec = 0;
 
115
 
 
116
    /* wait for the convertion */
 
117
    while (0) {
 
118
        int res;
 
119
 
 
120
        if (XPending(dpy)==0) {
 
121
            FD_ZERO(&fdset);
 
122
            FD_SET(ConnectionNumber(dpy), &fdset);
 
123
            res = select(ConnectionNumber(dpy)+1, &fdset, NULL, NULL,
 
124
                         &timeout);
 
125
            if (res <= 0) {
 
126
                ok = 0;
 
127
                break;
 
128
            }
 
129
        }
 
130
        if (res > 0 || XPending(dpy) > 0) {
 
131
            XNextEvent(dpy, &ev);
 
132
            if (ev.type == SelectionNotify && ev.xany.window == win) {
 
133
                ok = 1;
 
134
                break;
 
135
            }
 
136
        }
 
137
    }
 
138
 
 
139
    /* if success, return the data */
 
140
    if (ok) {
 
141
        Atom rtype;
 
142
        int bits;
 
143
        unsigned long len, bytes;
 
144
        unsigned char *data;
 
145
 
 
146
        if (XGetWindowProperty(dpy, win, clipatom, 0, MAXDATA/4, False,
 
147
                               XA_STRING, &rtype, &bits, &len, &bytes, &data)!=0)
 
148
            return NULL;
 
149
 
 
150
        if ((rtype!=XA_STRING) || (bits!=8)) {
 
151
            return NULL;
 
152
        } else {
 
153
            return (char*)data;
 
154
        }
 
155
    }
 
156
    return NULL;
 
157
}
 
158
 
 
159
 
 
160
int
 
161
main(int argc, char **argv)
 
162
{
 
163
    Display *dpy;
 
164
    int i, l;
 
165
    int buffer=0;
 
166
    char *buf;
 
167
    int status;
 
168
    char *display_name="";
 
169
    char *selection_name=NULL;
 
170
 
 
171
    for (i=1; i<argc; i++) {
 
172
        if (argv[i][0]=='-') {
 
173
            if (argv[i][1]=='h' || strcmp(argv[i], "--help")==0) {
 
174
                help(argv[0]);
 
175
                exit(0);
 
176
            } else if (strcmp(argv[i], "--version")==0) {
 
177
                puts(PROG_VERSION);
 
178
                exit(0);
 
179
            } else if (strcmp(argv[i],"-selection")==0
 
180
                       || strcmp(argv[i],"--selection")==0) {
 
181
                if (i<argc-1) {
 
182
                    selection_name = argv[++i];
 
183
                } else {
 
184
                    selection_name = "PRIMARY";
 
185
                }
 
186
            } else if (strcmp(argv[i],"-display")==0) {
 
187
                if (i<argc-1) {
 
188
                    display_name = argv[++i];
 
189
                } else {
 
190
                    help(argv[0]);
 
191
                    exit(0);
 
192
                }
 
193
            } else if (strcmp(argv[i],"-cutbuffer")==0
 
194
                       || strcmp(argv[i],"--cutbuffer")==0) {
 
195
                if (i<argc-1) {
 
196
                    i++;
 
197
                    if (sscanf(argv[i],"%i", &buffer)!=1) {
 
198
                        fprintf(stderr, "%s: could not convert \"%s\" to int\n",
 
199
                                argv[0], argv[i]);
 
200
                        exit(1);
 
201
                    }
 
202
                    if (buffer<0 || buffer > 7) {
 
203
                        fprintf(stderr, "%s: invalid buffer number %i\n",
 
204
                                argv[0], buffer);
 
205
                        exit(1);
 
206
                    }
 
207
                } else {
 
208
                    fprintf(stderr, "%s: invalid argument '%s'\n", argv[0],
 
209
                            argv[i]);
 
210
                    fprintf(stderr, "Try '%s --help' for more information.\n",
 
211
                            argv[0]);
 
212
                    exit(1);
 
213
                }
 
214
            }
 
215
        } else {
 
216
            fprintf(stderr, "%s: invalid argument '%s'\n", argv[0], argv[i]);
 
217
            fprintf(stderr, "Try '%s --help' for more information.\n",
 
218
                    argv[0]);
 
219
            exit(1);
 
220
        }
 
221
    }
 
222
    dpy = XOpenDisplay(display_name);
 
223
    if (!dpy) {
 
224
        fprintf(stderr, "%s: could not open display \"%s\"\n", argv[0],
 
225
                XDisplayName(display_name));
 
226
        exit(1);
 
227
    }
 
228
 
 
229
    if (selection_name) {
 
230
        buf = fetchSelection(dpy, selection_name, argv[0]);
 
231
    } else {
 
232
        buf = NULL;
 
233
    }
 
234
 
 
235
    if (buf == NULL) {
 
236
        buf = XFetchBuffer(dpy, &l, buffer);
 
237
    }
 
238
 
 
239
    if (buf == NULL) {
 
240
        status = 1;
 
241
    } else {
 
242
        if (write(STDOUT_FILENO, buf, l) == -1)
 
243
            status = errno;
 
244
        else
 
245
            status = 0;
 
246
    }
 
247
    XCloseDisplay(dpy);
 
248
    exit(status);
 
249
}
 
250