JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
added gridsel to gridwm
[dwm.git] / util.c
1 /*
2  * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
3  * See LICENSE file for license details.
4  */
5
6 #include <stdarg.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <sys/types.h>
11 #include <sys/wait.h>
12 #include <unistd.h>
13 #include <X11/Xatom.h>
14
15 #include "util.h"
16
17 static char *shell = NULL;
18
19 void
20 error(char *errstr, ...) {
21         va_list ap;
22         va_start(ap, errstr);
23         vfprintf(stderr, errstr, ap);
24         va_end(ap);
25         exit(1);
26 }
27
28 static void
29 bad_malloc(unsigned int size)
30 {
31         fprintf(stderr, "fatal: could not malloc() %d bytes\n",
32                         (int) size);
33         exit(1);
34 }
35
36 void *
37 emallocz(unsigned int size)
38 {
39         void *res = calloc(1, size);
40         if(!res)
41                 bad_malloc(size);
42         return res;
43 }
44
45 void *
46 emalloc(unsigned int size)
47 {
48         void *res = malloc(size);
49         if(!res)
50                 bad_malloc(size);
51         return res;
52 }
53
54 void *
55 erealloc(void *ptr, unsigned int size)
56 {
57         void *res = realloc(ptr, size);
58         if(!res)
59                 bad_malloc(size);
60         return res;
61 }
62
63 char *
64 estrdup(const char *str)
65 {
66         void *res = strdup(str);
67         if(!res)
68                 bad_malloc(strlen(str));
69         return res;
70 }
71
72 void
73 failed_assert(char *a, char *file, int line)
74 {
75         fprintf(stderr, "Assertion \"%s\" failed at %s:%d\n", a, file, line);
76         abort();
77 }
78
79 void
80 swap(void **p1, void **p2)
81 {
82         void *tmp = *p1;
83         *p1 = *p2;
84         *p2 = tmp;
85 }
86
87 void
88 spawn(Display *dpy, const char *cmd)
89 {
90         if(!shell && !(shell = getenv("SHELL")))
91                 shell = "/bin/sh";
92
93         if(!cmd)
94                 return;
95         if(fork() == 0) {
96                 if(fork() == 0) {
97                         if(dpy)
98                                 close(ConnectionNumber(dpy));
99                         setsid();
100                         fprintf(stderr, "gridwm: execlp %s %s -c %s", shell, shell, cmd);
101                         execlp(shell, shell, "-c", cmd, NULL);
102                         fprintf(stderr, "gridwm: execlp %s", cmd);
103                         perror(" failed");
104                 }
105                 exit (0);
106         }
107         wait(0);
108 }
109
110 void
111 pipe_spawn(char *buf, unsigned int len, Display *dpy, const char *cmd)
112 {
113         unsigned int l, n;
114         int pfd[2];
115
116         if(!shell && !(shell = getenv("SHELL")))
117                 shell = "/bin/sh";
118
119         if(!cmd)
120                 return;
121
122         if(pipe(pfd) == -1) {
123                 perror("pipe");
124                 exit(1);
125         }
126
127         if(fork() == 0) {
128                 if(dpy)
129                         close(ConnectionNumber(dpy));
130                 setsid();
131                 dup2(pfd[1], STDOUT_FILENO);
132                 close(pfd[0]);
133                 close(pfd[1]);
134                 execlp(shell, shell, "-c", cmd, NULL);
135                 fprintf(stderr, "gridwm: execlp %s", cmd);
136                 perror(" failed");
137         }
138         else {
139                 n = 0;
140                 close(pfd[1]);
141                 while(l > n) {
142                         if((l = read(pfd[0], buf + n, len - n)) < 1)
143                                 break;
144                         n += l;
145                 }
146                 close(pfd[0]);
147                 buf[n - 1] = 0;
148         }
149         wait(0);
150 }
151
152
153 unsigned char *
154 getselection(unsigned long offset, unsigned long *len, unsigned long *remain)
155 {
156         Display *dpy;
157         Atom xa_clip_string;
158         Window w;
159         XEvent ev;
160         Atom typeret;
161         int format;
162         unsigned char *data;
163         unsigned char *result = NULL;
164
165         dpy = XOpenDisplay(0);
166         if(!dpy)
167                 return NULL;
168         xa_clip_string = XInternAtom(dpy, "_SEL_STRING", False);
169         w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 10, 10, 200, 200,
170                         1, CopyFromParent, CopyFromParent);
171         XConvertSelection(dpy, XA_PRIMARY, XA_STRING, xa_clip_string,
172                         w, CurrentTime);
173         XFlush(dpy);
174         XNextEvent(dpy, &ev);
175         if(ev.type == SelectionNotify && ev.xselection.property != None) {
176                 XGetWindowProperty(dpy, w, ev.xselection.property, offset, 4096L, False,
177                                 AnyPropertyType, &typeret, &format, len, remain, &data);
178                 if(*len) {
179                         result = emalloc(sizeof(unsigned char) * *len);
180                         memcpy(result, data, *len);
181                 }
182                 XDeleteProperty(dpy, w, ev.xselection.property);
183         }
184         XDestroyWindow(dpy, w);
185         XCloseDisplay(dpy);
186         return result;
187 }