vmware userland helper
1/*
2 * Copyright (c) 2010 joshua stein <jcs@jcs.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <string.h>
18#include <stdlib.h>
19#include <stdio.h>
20#include <err.h>
21#include <vis.h>
22
23#include <X11/Xlib.h>
24#include <X11/Xatom.h>
25#include <X11/Xmu/Atoms.h>
26
27#include "vmwh.h"
28
29#define XCLIP_VERSION "xclip -version 2>&1"
30#define XCLIP_READ "xclip -out -selection clipboard"
31#define XCLIP_WRITE "xclip -in -selection clipboard"
32
33struct xinfo {
34 Display *dpy;
35 int screen;
36 Window win;
37 Window root;
38} x11;
39
40void
41x11_init(void) {
42 bzero(&x11, sizeof(struct xinfo));
43
44 if (!(x11.dpy = XOpenDisplay(NULL)))
45 errx(1, "unable to open display %s", XDisplayName(NULL));
46
47 x11.screen = DefaultScreen(x11.dpy);
48 x11.root = RootWindow(x11.dpy, x11.screen);
49
50 x11.win = XCreateSimpleWindow(x11.dpy, XDefaultRootWindow(x11.dpy),
51 0, 0, 1, 1, 0, 0, 0);
52
53 XSelectInput(x11.dpy, x11.win, PropertyChangeMask);
54}
55
56void
57x11_verify_xclip_presence(void) {
58 FILE *xclip;
59 char *lbuf;
60 int found = 0;
61 size_t len;
62
63 xclip = popen(XCLIP_VERSION, "r");
64 if (xclip == NULL)
65 errx(1, "couldn't run xclip (" XCLIP_VERSION ")");
66
67 while ((lbuf = fgetln(xclip, &len)) != NULL)
68 if (strncmp(lbuf, "xclip version", 13) == 0)
69 found = 1;
70
71 pclose(xclip);
72
73 if (!found)
74 errx(1, "couldn't run xclip; is it installed?");
75}
76
77void
78x11_set_clipboard(char *buf)
79{
80 FILE *xclip;
81
82 if (debug) {
83 char visbuf[strlen(buf) * 4];
84 strnvis(visbuf, buf, sizeof(visbuf), VIS_TAB | VIS_NL | VIS_CSTYLE);
85 printf("x11_set_clipboard: \"%s\"\n", visbuf);
86 }
87
88 xclip = popen(XCLIP_WRITE, "w");
89 if (xclip == NULL) {
90 warn("couldn't write to xclip (" XCLIP_WRITE ")");
91 return;
92 }
93
94 fprintf(xclip, "%s", buf);
95 fflush(xclip);
96
97 pclose(xclip);
98}
99
100int
101x11_get_clipboard(char **buf)
102{
103 FILE *xclip;
104 char tbuf[1024];
105 size_t len, buflen = 0;
106
107 xclip = popen(XCLIP_READ, "r");
108 if (xclip == NULL) {
109 warn("couldn't read from xclip (" XCLIP_READ ")");
110 return (0);
111 }
112
113 while ((len = fread(tbuf, 1, 4, xclip)) != 0) {
114 if (*buf == NULL) {
115 *buf = (char *)malloc(len + 2);
116 memcpy(*buf, tbuf, len);
117 buflen = len;
118 } else {
119 if ((*buf = (char *)realloc(*buf, buflen + len + 2)) == NULL)
120 err(1, "realloc");
121
122 memcpy(*buf + buflen, tbuf, len);
123 buflen += len;
124 }
125 }
126 if (*buf != NULL)
127 buf[0][buflen] = '\0';
128
129 pclose(xclip);
130
131 if (debug) {
132 if (*buf == NULL)
133 printf("x11_get_clipboard: nothing there\n");
134 else {
135 char visbuf[strlen(*buf) * 4];
136 strnvis(visbuf, *buf, sizeof(visbuf), VIS_TAB | VIS_NL | VIS_CSTYLE);
137 printf("x11_get_clipboard: \"%s\"\n", visbuf);
138 }
139 }
140
141 if (*buf == NULL)
142 return (0);
143 else
144 return (1);
145}
146
147void
148x11_set_mouse_position(int x, int y)
149{
150 XWarpPointer(x11.dpy, None, x11.root, 0, 0, 0, 0, x, y);
151 XFlush(x11.dpy);
152}