1706f2543Smrg/* 2706f2543Smrg * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina. 3706f2543Smrg * 4706f2543Smrg * All Rights Reserved. 5706f2543Smrg * 6706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining 7706f2543Smrg * a copy of this software and associated documentation files (the 8706f2543Smrg * "Software"), to deal in the Software without restriction, including 9706f2543Smrg * without limitation on the rights to use, copy, modify, merge, 10706f2543Smrg * publish, distribute, sublicense, and/or sell copies of the Software, 11706f2543Smrg * and to permit persons to whom the Software is furnished to do so, 12706f2543Smrg * subject to the following conditions: 13706f2543Smrg * 14706f2543Smrg * The above copyright notice and this permission notice (including the 15706f2543Smrg * next paragraph) shall be included in all copies or substantial 16706f2543Smrg * portions of the Software. 17706f2543Smrg * 18706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19706f2543Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20706f2543Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21706f2543Smrg * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS 22706f2543Smrg * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 23706f2543Smrg * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24706f2543Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25706f2543Smrg * SOFTWARE. 26706f2543Smrg */ 27706f2543Smrg 28706f2543Smrg/* 29706f2543Smrg * Authors: 30706f2543Smrg * Rickard E. (Rik) Faith <faith@redhat.com> 31706f2543Smrg * 32706f2543Smrg */ 33706f2543Smrg 34706f2543Smrg/** \file 35706f2543Smrg * This code queries and modifies the connection block. */ 36706f2543Smrg 37706f2543Smrg#ifdef HAVE_DMX_CONFIG_H 38706f2543Smrg#include <dmx-config.h> 39706f2543Smrg#endif 40706f2543Smrg 41706f2543Smrg#include "dmx.h" 42706f2543Smrg#include "dmxcb.h" 43706f2543Smrg#include "dmxinput.h" 44706f2543Smrg#include "dmxlog.h" 45706f2543Smrg 46706f2543Smrgextern int connBlockScreenStart; 47706f2543Smrg 48706f2543Smrg#ifdef PANORAMIX 49706f2543Smrgextern int PanoramiXPixWidth; 50706f2543Smrgextern int PanoramiXPixHeight; 51706f2543Smrgextern int PanoramiXNumScreens; 52706f2543Smrg#endif 53706f2543Smrg 54706f2543Smrg int dmxGlobalWidth, dmxGlobalHeight; 55706f2543Smrg 56706f2543Smrg/** We may want the wall dimensions to be different from the bounding 57706f2543Smrg * box dimensions that Xinerama computes, so save those and update them 58706f2543Smrg * here. 59706f2543Smrg */ 60706f2543Smrgvoid dmxSetWidthHeight(int width, int height) 61706f2543Smrg{ 62706f2543Smrg dmxGlobalWidth = width; 63706f2543Smrg dmxGlobalHeight = height; 64706f2543Smrg} 65706f2543Smrg 66706f2543Smrg/** Computes the global bounding box for DMX. This may be larger than 67706f2543Smrg * the one computed by Xinerama because of the DMX configuration 68706f2543Smrg * file. */ 69706f2543Smrgvoid dmxComputeWidthHeight(DMXRecomputeFlag flag) 70706f2543Smrg{ 71706f2543Smrg int i; 72706f2543Smrg DMXScreenInfo *dmxScreen; 73706f2543Smrg int w = 0; 74706f2543Smrg int h = 0; 75706f2543Smrg 76706f2543Smrg for (i = 0; i < dmxNumScreens; i++) { 77706f2543Smrg /* Don't use root* here because this is 78706f2543Smrg * the global bounding box. */ 79706f2543Smrg dmxScreen = &dmxScreens[i]; 80706f2543Smrg if (w < dmxScreen->scrnWidth + dmxScreen->rootXOrigin) 81706f2543Smrg w = dmxScreen->scrnWidth + dmxScreen->rootXOrigin; 82706f2543Smrg if (h < dmxScreen->scrnHeight + dmxScreen->rootYOrigin) 83706f2543Smrg h = dmxScreen->scrnHeight + dmxScreen->rootYOrigin; 84706f2543Smrg } 85706f2543Smrg if (!dmxGlobalWidth && !dmxGlobalHeight) { 86706f2543Smrg dmxLog(dmxInfo, "Using %dx%d as global bounding box\n", w, h); 87706f2543Smrg } else { 88706f2543Smrg switch (flag) { 89706f2543Smrg case DMX_NO_RECOMPUTE_BOUNDING_BOX: 90706f2543Smrg dmxLog(dmxInfo, 91706f2543Smrg "Using old bounding box (%dx%d) instead of new (%dx%d)\n", 92706f2543Smrg dmxGlobalWidth, dmxGlobalHeight, w, h); 93706f2543Smrg w = dmxGlobalWidth; 94706f2543Smrg h = dmxGlobalHeight; 95706f2543Smrg break; 96706f2543Smrg case DMX_RECOMPUTE_BOUNDING_BOX: 97706f2543Smrg dmxLog(dmxInfo, 98706f2543Smrg "Using %dx%d as global bounding box, instead of %dx%d\n", 99706f2543Smrg w, h, dmxGlobalWidth, dmxGlobalHeight); 100706f2543Smrg break; 101706f2543Smrg } 102706f2543Smrg } 103706f2543Smrg 104706f2543Smrg dmxGlobalWidth = w; 105706f2543Smrg dmxGlobalHeight = h; 106706f2543Smrg} 107706f2543Smrg 108706f2543Smrg/** A callback routine that hooks into Xinerama and provides a 109706f2543Smrg * convenient place to print summary log information during server 110706f2543Smrg * startup. This routine does not modify any values. */ 111706f2543Smrgvoid dmxConnectionBlockCallback(void) 112706f2543Smrg{ 113706f2543Smrg xWindowRoot *root = (xWindowRoot *)(ConnectionInfo+connBlockScreenStart); 114706f2543Smrg int offset = connBlockScreenStart + sizeof(xWindowRoot); 115706f2543Smrg int i; 116706f2543Smrg Bool *found = NULL; 117706f2543Smrg 118706f2543Smrg MAXSCREENSALLOC(found); 119706f2543Smrg if (!found) 120706f2543Smrg dmxLog(dmxFatal, "dmxConnectionBlockCallback: out of memory\n"); 121706f2543Smrg 122706f2543Smrg dmxLog(dmxInfo, "===== Start of Summary =====\n"); 123706f2543Smrg#ifdef PANORAMIX 124706f2543Smrg if (!noPanoramiXExtension) { 125706f2543Smrg if (dmxGlobalWidth && dmxGlobalHeight 126706f2543Smrg && (dmxGlobalWidth != PanoramiXPixWidth 127706f2543Smrg || dmxGlobalHeight != PanoramiXPixHeight)) { 128706f2543Smrg dmxLog(dmxInfo, 129706f2543Smrg "Changing Xinerama dimensions from %d %d to %d %d\n", 130706f2543Smrg PanoramiXPixWidth, PanoramiXPixHeight, 131706f2543Smrg dmxGlobalWidth, dmxGlobalHeight); 132706f2543Smrg PanoramiXPixWidth = root->pixWidth = dmxGlobalWidth; 133706f2543Smrg PanoramiXPixHeight = root->pixHeight = dmxGlobalHeight; 134706f2543Smrg } else { 135706f2543Smrg dmxGlobalWidth = PanoramiXPixWidth; 136706f2543Smrg dmxGlobalHeight = PanoramiXPixHeight; 137706f2543Smrg } 138706f2543Smrg dmxLog(dmxInfo, "%d screens configured with Xinerama (%d %d)\n", 139706f2543Smrg PanoramiXNumScreens, PanoramiXPixWidth, PanoramiXPixHeight); 140706f2543Smrg for (i = 0; i < PanoramiXNumScreens; i++) found[i] = FALSE; 141706f2543Smrg } else { 142706f2543Smrg#endif 143706f2543Smrg /* This never happens because we're 144706f2543Smrg * either called from a Xinerama 145706f2543Smrg * callback or during reconfiguration 146706f2543Smrg * (which only works with Xinerama on). 147706f2543Smrg * In any case, be reasonable. */ 148706f2543Smrg dmxLog(dmxInfo, "%d screens configured (%d %d)\n", 149706f2543Smrg screenInfo.numScreens, root->pixWidth, root->pixHeight); 150706f2543Smrg#ifdef PANORAMIX 151706f2543Smrg } 152706f2543Smrg#endif 153706f2543Smrg 154706f2543Smrg for (i = 0; i < root->nDepths; i++) { 155706f2543Smrg xDepth *depth = (xDepth *)(ConnectionInfo + offset); 156706f2543Smrg int voffset = offset + sizeof(xDepth); 157706f2543Smrg xVisualType *visual = (xVisualType *)(ConnectionInfo + voffset); 158706f2543Smrg int j; 159706f2543Smrg 160706f2543Smrg dmxLog(dmxInfo, "%d visuals at depth %d:\n", 161706f2543Smrg depth->nVisuals, depth->depth); 162706f2543Smrg for (j = 0; j < depth->nVisuals; j++, visual++) { 163706f2543Smrg XVisualInfo vi; 164706f2543Smrg 165706f2543Smrg vi.visual = NULL; 166706f2543Smrg vi.visualid = visual->visualID; 167706f2543Smrg vi.screen = 0; 168706f2543Smrg vi.depth = depth->depth; 169706f2543Smrg vi.class = visual->class; 170706f2543Smrg vi.red_mask = visual->redMask; 171706f2543Smrg vi.green_mask = visual->greenMask; 172706f2543Smrg vi.blue_mask = visual->blueMask; 173706f2543Smrg vi.colormap_size = visual->colormapEntries; 174706f2543Smrg vi.bits_per_rgb = visual->bitsPerRGB; 175706f2543Smrg dmxLogVisual(NULL, &vi, 0); 176706f2543Smrg 177706f2543Smrg#ifdef PANORAMIX 178706f2543Smrg if (!noPanoramiXExtension) { 179706f2543Smrg int k; 180706f2543Smrg for (k = 0; k < PanoramiXNumScreens; k++) { 181706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[k]; 182706f2543Smrg 183706f2543Smrg if (dmxScreen->beDisplay) { 184706f2543Smrg XVisualInfo *pvi = 185706f2543Smrg &dmxScreen->beVisuals[dmxScreen->beDefVisualIndex]; 186706f2543Smrg if (pvi->depth == depth->depth && 187706f2543Smrg pvi->class == visual->class) 188706f2543Smrg found[k] = TRUE; 189706f2543Smrg } else { 190706f2543Smrg /* Screen #k is detatched, so it always succeeds */ 191706f2543Smrg found[k] = TRUE; 192706f2543Smrg } 193706f2543Smrg } 194706f2543Smrg } 195706f2543Smrg#endif 196706f2543Smrg } 197706f2543Smrg offset = voffset + depth->nVisuals * sizeof(xVisualType); 198706f2543Smrg } 199706f2543Smrg 200706f2543Smrg dmxInputLogDevices(); 201706f2543Smrg dmxLog(dmxInfo, "===== End of Summary =====\n"); 202706f2543Smrg 203706f2543Smrg#ifdef PANORAMIX 204706f2543Smrg if (!noPanoramiXExtension) { 205706f2543Smrg Bool fatal = FALSE; 206706f2543Smrg for (i = 0; i < PanoramiXNumScreens; i++) { 207706f2543Smrg fatal |= !found[i]; 208706f2543Smrg if (!found[i]) { 209706f2543Smrg dmxLog(dmxError, 210706f2543Smrg "The default visual for screen #%d does not match " 211706f2543Smrg "any of the\n", i); 212706f2543Smrg dmxLog(dmxError, 213706f2543Smrg "consolidated visuals from Xinerama (listed above)\n"); 214706f2543Smrg } 215706f2543Smrg } 216706f2543Smrg if (fatal) 217706f2543Smrg dmxLog(dmxFatal, 218706f2543Smrg "dmxConnectionBlockCallback: invalid screen(s) found"); 219706f2543Smrg } 220706f2543Smrg#endif 221706f2543Smrg MAXSCREENSFREE(found); 222706f2543Smrg} 223