garbeam@2: /* garbeam@2: * (C)opyright MMVI Anselm R. Garbe garbeam@2: * See LICENSE file for license details. garbeam@2: */ garbeam@2: garbeam@2: #include garbeam@2: #include garbeam@2: #include garbeam@3: #include garbeam@5: #include garbeam@5: #include garbeam@5: #include garbeam@11: #include garbeam@5: garbeam@5: #include "util.h" garbeam@2: garbeam@6: static char *shell = NULL; garbeam@6: garbeam@2: void garbeam@2: error(char *errstr, ...) { garbeam@2: va_list ap; garbeam@2: va_start(ap, errstr); garbeam@2: vfprintf(stderr, errstr, ap); garbeam@2: va_end(ap); garbeam@2: exit(1); garbeam@2: } garbeam@2: garbeam@3: static void garbeam@3: bad_malloc(unsigned int size) garbeam@3: { garbeam@3: fprintf(stderr, "fatal: could not malloc() %d bytes\n", garbeam@3: (int) size); garbeam@3: exit(1); garbeam@3: } garbeam@3: garbeam@3: void * garbeam@3: emallocz(unsigned int size) garbeam@3: { garbeam@3: void *res = calloc(1, size); garbeam@3: if(!res) garbeam@3: bad_malloc(size); garbeam@3: return res; garbeam@3: } garbeam@3: garbeam@3: void * garbeam@3: emalloc(unsigned int size) garbeam@3: { garbeam@3: void *res = malloc(size); garbeam@3: if(!res) garbeam@3: bad_malloc(size); garbeam@3: return res; garbeam@3: } garbeam@3: garbeam@3: void * garbeam@3: erealloc(void *ptr, unsigned int size) garbeam@3: { garbeam@3: void *res = realloc(ptr, size); garbeam@3: if(!res) garbeam@3: bad_malloc(size); garbeam@3: return res; garbeam@3: } garbeam@3: garbeam@3: char * garbeam@3: estrdup(const char *str) garbeam@3: { garbeam@3: void *res = strdup(str); garbeam@3: if(!res) garbeam@3: bad_malloc(strlen(str)); garbeam@3: return res; garbeam@3: } garbeam@3: garbeam@3: void garbeam@3: failed_assert(char *a, char *file, int line) garbeam@3: { garbeam@3: fprintf(stderr, "Assertion \"%s\" failed at %s:%d\n", a, file, line); garbeam@3: abort(); garbeam@3: } garbeam@3: garbeam@3: void garbeam@3: swap(void **p1, void **p2) garbeam@3: { garbeam@3: void *tmp = *p1; garbeam@3: *p1 = *p2; garbeam@3: *p2 = tmp; garbeam@3: } garbeam@5: garbeam@5: void garbeam@6: spawn(Display *dpy, const char *cmd) garbeam@5: { garbeam@6: if(!shell && !(shell = getenv("SHELL"))) garbeam@6: shell = "/bin/sh"; garbeam@6: garbeam@6: if(!cmd) garbeam@5: return; garbeam@5: if(fork() == 0) { garbeam@5: if(fork() == 0) { garbeam@5: if(dpy) garbeam@5: close(ConnectionNumber(dpy)); garbeam@9: setsid(); garbeam@9: fprintf(stderr, "gridwm: execlp %s %s -c %s", shell, shell, cmd); garbeam@9: execlp(shell, shell, "-c", cmd, NULL); garbeam@9: fprintf(stderr, "gridwm: execlp %s", cmd); garbeam@5: perror(" failed"); garbeam@5: } garbeam@5: exit (0); garbeam@5: } garbeam@5: wait(0); garbeam@5: } garbeam@6: garbeam@6: void garbeam@6: pipe_spawn(char *buf, unsigned int len, Display *dpy, const char *cmd) garbeam@6: { garbeam@6: unsigned int l, n; garbeam@6: int pfd[2]; garbeam@6: garbeam@6: if(!shell && !(shell = getenv("SHELL"))) garbeam@6: shell = "/bin/sh"; garbeam@6: garbeam@6: if(!cmd) garbeam@6: return; garbeam@6: garbeam@6: if(pipe(pfd) == -1) { garbeam@6: perror("pipe"); garbeam@6: exit(1); garbeam@6: } garbeam@6: garbeam@6: if(fork() == 0) { garbeam@6: if(dpy) garbeam@6: close(ConnectionNumber(dpy)); garbeam@9: setsid(); garbeam@6: dup2(pfd[1], STDOUT_FILENO); garbeam@6: close(pfd[0]); garbeam@6: close(pfd[1]); garbeam@9: execlp(shell, shell, "-c", cmd, NULL); garbeam@9: fprintf(stderr, "gridwm: execlp %s", cmd); garbeam@6: perror(" failed"); garbeam@6: } garbeam@6: else { garbeam@6: n = 0; garbeam@6: close(pfd[1]); garbeam@6: while(l > n) { garbeam@6: if((l = read(pfd[0], buf + n, len - n)) < 1) garbeam@6: break; garbeam@6: n += l; garbeam@6: } garbeam@6: close(pfd[0]); garbeam@6: buf[n - 1] = 0; garbeam@6: } garbeam@6: wait(0); garbeam@6: } garbeam@11: garbeam@11: garbeam@11: unsigned char * garbeam@11: getselection(unsigned long offset, unsigned long *len, unsigned long *remain) garbeam@11: { garbeam@11: Display *dpy; garbeam@11: Atom xa_clip_string; garbeam@11: Window w; garbeam@11: XEvent ev; garbeam@11: Atom typeret; garbeam@11: int format; garbeam@11: unsigned char *data; garbeam@11: unsigned char *result = NULL; garbeam@11: garbeam@11: dpy = XOpenDisplay(0); garbeam@11: if(!dpy) garbeam@11: return NULL; garbeam@11: xa_clip_string = XInternAtom(dpy, "_SEL_STRING", False); garbeam@11: w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 10, 10, 200, 200, garbeam@11: 1, CopyFromParent, CopyFromParent); garbeam@11: XConvertSelection(dpy, XA_PRIMARY, XA_STRING, xa_clip_string, garbeam@11: w, CurrentTime); garbeam@11: XFlush(dpy); garbeam@11: XNextEvent(dpy, &ev); garbeam@11: if(ev.type == SelectionNotify && ev.xselection.property != None) { garbeam@11: XGetWindowProperty(dpy, w, ev.xselection.property, offset, 4096L, False, garbeam@11: AnyPropertyType, &typeret, &format, len, remain, &data); garbeam@11: if(*len) { garbeam@11: result = emalloc(sizeof(unsigned char) * *len); garbeam@11: memcpy(result, data, *len); garbeam@11: } garbeam@11: XDeleteProperty(dpy, w, ev.xselection.property); garbeam@11: } garbeam@11: XDestroyWindow(dpy, w); garbeam@11: XCloseDisplay(dpy); garbeam@11: return result; garbeam@11: }