#ifdef notdef set -x exec cc -O2 -std=c99 -pedantic -Wall $0 -fPIC -o lib${0%.c}.so -shared #endif #define _XOPEN_SOURCE 600 #include #include #include #include #include #include const char SETTINGS[] = "XINERAMA_SCREENS"; const char SEP[] = ";"; static XineramaScreenInfo* screens; static int num_screens; typedef XineramaScreenInfo* (queryfn)(Display*, int*); typedef Status (versionfn)(Display*, int*, int*); typedef Bool (extensionfn)(Display*, int*, int*); typedef Bool (activefn)(Display*); static void* libxinerama; static queryfn* queryscreens; static extensionfn* queryextension; static versionfn* queryversion; static activefn* isactive; static _Bool init() { char *str, *p, *q; int i; if(screens || libxinerama) return screens; str = getenv(SETTINGS); if(!str) { libxinerama = dlopen("libXinerama.so.1", RTLD_GLOBAL | RTLD_LAZY); if(!libxinerama) abort(); isactive = (activefn*) (uintptr_t)dlsym(libxinerama, "XineramaIsActive"); queryversion = (versionfn*) (uintptr_t)dlsym(libxinerama, "XineramaQueryVersion"); queryextension = (extensionfn*) (uintptr_t)dlsym(libxinerama, "XineramaQueryExtension"); queryscreens = (queryfn*) (uintptr_t)dlsym(libxinerama, "XineramaQueryScreens"); return False; } for(i=1, p=str; strchr(p, *SEP); p++) i++; screens = malloc(i * sizeof *screens); i = 0; str = strdup(str); for(q=str; (p = strtok(q, SEP)); q=NULL) { if(sscanf(p, "%hd,%hd %hdx%hd", &screens[i].x_org, &screens[i].y_org, &screens[i].width, &screens[i].height) == 4) i++; } num_screens = i; return True; } Bool XineramaQueryExtension(Display *dpy, int *event_base, int *error_base) { if(!init()) return queryextension(dpy, event_base, error_base); *event_base = 0; *error_base = 0; return True; } Status XineramaQueryVersion(Display *dpy, int *major, int *minor) { if(!init()) return queryversion(dpy, major, minor); *major = 1; *minor = 1; return True; } Bool XineramaIsActive(Display *dpy) { if(!init()) return isactive(dpy); return num_screens > 0; } XineramaScreenInfo* XineramaQueryScreens(Display *dpy, int *number) { XineramaScreenInfo *ret; if(!init()) return queryscreens(dpy, number); *number = num_screens; ret = Xmalloc(num_screens * sizeof *screens); memcpy(ret, screens, num_screens * sizeof *screens); return screens; }