wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

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