**************************************************************************/
#include <X11/extensions/Xrender.h>
+#include <X11/extensions/Xrandr.h>
+
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "server.h"
+#include "config.h"
#include "task.h"
#include "window.h"
void cleanup_server()
{
if (server.colormap) XFreeColormap(server.dsp, server.colormap);
- if (server.monitor) free(server.monitor);
+ if (server.colormap32) XFreeColormap(server.dsp, server.colormap32);
+ if (server.monitor) {
+ int i;
+ for (i=0; i<server.nb_monitor; ++i)
+ g_strfreev(server.monitor[i].names);
+ free(server.monitor);
+ }
if (server.gc) XFreeGC(server.dsp, server.gc);
}
void get_monitors()
{
- if (server.monitor) free(server.monitor);
+ if (server.monitor) {
+ int i;
+ for (i=0; i<server.nb_monitor; ++i)
+ g_strfreev(server.monitor[i].names);
+ free(server.monitor);
+ }
server.nb_monitor = 0;
server.monitor = 0;
int i, j, nbmonitor;
if (XineramaIsActive(server.dsp)) {
XineramaScreenInfo *info = XineramaQueryScreens(server.dsp, &nbmonitor);
-
- if (info && nbmonitor > 0) {
+ XRRScreenResources *res = XRRGetScreenResourcesCurrent(server.dsp, server.root_win);
+
+ if (res->ncrtc >= nbmonitor) {
+ // use xrandr to identify monitors (does not work with proprietery nvidia drivers)
+ printf("xRandr: Found crtc's: %d\n", res->ncrtc );
+ server.monitor = malloc(res->ncrtc * sizeof(Monitor));
+ for (i=0; i<res->ncrtc; ++i) {
+ XRRCrtcInfo* crtc_info = XRRGetCrtcInfo(server.dsp, res, res->crtcs[i]);
+ server.monitor[i].x = crtc_info->x;
+ server.monitor[i].y = crtc_info->y;
+ server.monitor[i].width = crtc_info->width;
+ server.monitor[i].height = crtc_info->height;
+ server.monitor[i].names = malloc((crtc_info->noutput+1) * sizeof(char*));
+ for (j=0; j<crtc_info->noutput; ++j) {
+ XRROutputInfo* output_info = XRRGetOutputInfo(server.dsp, res, crtc_info->outputs[j]);
+ printf("xRandr: Linking output %s with crtc %d\n", output_info->name, i);
+ server.monitor[i].names[j] = g_strdup(output_info->name);
+ XRRFreeOutputInfo(output_info);
+ }
+ server.monitor[i].names[j] = 0;
+ XRRFreeCrtcInfo(crtc_info);
+ }
+ nbmonitor = res->ncrtc;
+ }
+ else if (info && nbmonitor > 0) {
server.monitor = malloc(nbmonitor * sizeof(Monitor));
for (i=0 ; i < nbmonitor ; i++) {
server.monitor[i].x = info[i].x_org;
server.monitor[i].y = info[i].y_org;
server.monitor[i].width = info[i].width;
server.monitor[i].height = info[i].height;
+ server.monitor[i].names = 0;
}
- XFree(info);
-
- // ordered monitor
- qsort(server.monitor, nbmonitor, sizeof(Monitor), compareMonitorIncluded);
-
- // remove monitor included into another one
- i = 0;
- while (i < nbmonitor) {
- for (j=0; j < i ; j++) {
- if (compareMonitorIncluded(&server.monitor[i], &server.monitor[j]) > 0) {
- goto next;
- }
+ }
+
+ // ordered monitor
+ qsort(server.monitor, nbmonitor, sizeof(Monitor), compareMonitorIncluded);
+
+ // remove monitor included into another one
+ i = 0;
+ while (i < nbmonitor) {
+ for (j=0; j < i ; j++) {
+ if (compareMonitorIncluded(&server.monitor[i], &server.monitor[j]) > 0) {
+ goto next;
}
- i++;
}
-next:
- server.nb_monitor = i;
- server.monitor = realloc(server.monitor, server.nb_monitor * sizeof(Monitor));
- qsort(server.monitor, server.nb_monitor, sizeof(Monitor), compareMonitorPos);
+ i++;
}
+next:
+ for (j=i; j<server.nb_monitor; ++j)
+ g_strfreev(server.monitor[j].names);
+ server.nb_monitor = i;
+ server.monitor = realloc(server.monitor, server.nb_monitor * sizeof(Monitor));
+ qsort(server.monitor, server.nb_monitor, sizeof(Monitor), compareMonitorPos);
+
+ XRRFreeScreenResources(res);
+ XFree(info);
}
if (!server.nb_monitor) {
server.composite_manager = XGetSelectionOwner(server.dsp, server.atom._NET_WM_CM_S0);
if (server.colormap)
XFreeColormap(server.dsp, server.colormap);
+ if (server.colormap32)
+ XFreeColormap(server.dsp, server.colormap32);
+
+ if (visual) {
+ server.visual32 = visual;
+ server.colormap32 = XCreateColormap(server.dsp, server.root_win, visual, AllocNone);
+ }
- if (visual && server.composite_manager != None) {
+ if (visual && server.composite_manager != None && snapshot_path == 0) {
XSetWindowAttributes attrs;
attrs.event_mask = StructureNotifyMask;
XChangeWindowAttributes (server.dsp, server.composite_manager, CWEventMask, &attrs);
server.visual = visual;
}
else {
+ // no composite manager or snapshot mode => fake transparency
real_transparency = 0;
server.depth = DefaultDepth(server.dsp, server.screen);
printf("real transparency off.... depth: %d\n", server.depth);