hack.c (2759B)
1 /* Copyright ©2008 Kris Maglione <maglione.k at Gmail> 2 * See LICENSE file for license details. 3 */ 4 #include "hack.h" 5 #include <dlfcn.h> 6 #include <stdbool.h> 7 #include <stdio.h> 8 #include <sys/time.h> 9 #include <sys/types.h> 10 #include <time.h> 11 #include <unistd.h> 12 13 #include "util.c" 14 #include "x11.c" 15 16 enum { 17 Timeout = 10, 18 }; 19 20 static void* xlib; 21 22 static long transient; 23 static Atom types[32]; 24 static long ntypes; 25 static char** tags; 26 static long pid; 27 static long stime; 28 static char hostname[256]; 29 static long starttime; 30 31 typedef Window (*mapfn)(Display*, Window); 32 33 static Window (*mapwindow)(Display*, Window); 34 static Window (*mapraised)(Display*, Window); 35 36 static void 37 init(Display *d) { /* Hrm... assumes one display... */ 38 char *toks[nelem(types)]; 39 char *s, *p; 40 long n; 41 int i; 42 43 xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY); 44 if(xlib == nil) 45 return; 46 mapwindow = (mapfn)(uintptr_t)dlsym(xlib, "XMapWindow"); 47 mapraised = (mapfn)(uintptr_t)dlsym(xlib, "XMapRaised"); 48 49 unsetenv("LD_PRELOAD"); 50 51 if((s = getenv("WMII_HACK_TRANSIENT"))) { 52 if(getlong(s, &n)) 53 transient = n; 54 unsetenv("WMII_HACK_TRANSIENT"); 55 } 56 if((s = getenv("WMII_HACK_TYPE"))) { 57 s = strdup(s); 58 unsetenv("WMII_HACK_TYPE"); 59 60 n = tokenize(toks, nelem(toks), s, ','); 61 for(i=0; i < n; i++) { 62 for(p=toks[i]; *p; p++) 63 if(*p >= 'a' && *p <= 'z') 64 *p += 'A' - 'a'; 65 toks[i] = smprint("_NET_WM_WINDOW_TYPE_%s", toks[i]); 66 } 67 XInternAtoms(d, toks, n, false, types); 68 ntypes = n; 69 for(i=0; i < n; i++) 70 free(toks[i]); 71 free(s); 72 } 73 if((s = getenv("WMII_HACK_TAGS"))) { 74 s = strdup(s); 75 unsetenv("WMII_HACK_TAGS"); 76 77 n = tokenize(toks, nelem(toks)-1, s, '+'); 78 tags = strlistdup(toks, n); 79 free(s); 80 } 81 if((s = getenv("WMII_HACK_TIME"))) { 82 getlong(s, &stime); 83 unsetenv("WMII_HACK_TIME"); 84 } 85 86 pid = getpid(); 87 gethostname(hostname, sizeof hostname - 1); 88 } 89 90 static void 91 setprops(Display *d, Window w) { 92 long *l; 93 94 if(!xlib) 95 init(d); 96 97 if(getprop_long(d, w, "_NET_WM_PID", "CARDINAL", 0L, &l, 1L)) 98 free(l); 99 else { 100 changeprop_long(d, w, "_NET_WM_PID", "CARDINAL", &pid, 1); 101 changeprop_string(d, w, "WM_CLIENT_MACHINE", hostname); 102 } 103 104 /* Kludge. */ 105 if(starttime == 0) 106 starttime = time(0); 107 else if(time(0) > starttime + Timeout) 108 return; 109 110 if(transient) 111 changeprop_long(d, w, "WM_TRANSIENT_FOR", "WINDOW", &transient, 1); 112 if(ntypes) 113 changeprop_long(d, w, "_NET_WM_WINDOW_TYPE", "ATOM", (long*)types, ntypes); 114 if(tags) 115 changeprop_textlist(d, w, "_WMII_TAGS", "UTF8_STRING", tags); 116 if(stime) 117 changeprop_long(d, w, "_WMII_LAUNCH_TIME", "CARDINAL", &stime, 1); 118 } 119 120 int 121 XMapWindow(Display *d, Window w) { 122 123 setprops(d, w); 124 return mapwindow(d, w); 125 } 126 127 int 128 XMapRaised(Display *d, Window w) { 129 130 setprops(d, w); 131 return mapraised(d, w); 132 } 133