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