/* * Copyright 2011 VMWare, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Author: Unknown at vmware */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "vmware_common.h" #ifndef HAVE_XORG_SERVER_1_5_0 #include #include #endif static int VMWAREParseTopologyElement(ScrnInfoPtr pScrn, unsigned int output, const char *elementName, const char *element, const char *expectedTerminators, Bool needTerminator, unsigned int *outValue) { char buf[10] = {0, }; size_t i = 0; int retVal = -1; const char *str = element; for (i = 0; str[i] >= '0' && str[i] <= '9'; i++); if (i == 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %u: unable to parse %s.\n", output, elementName); goto exit; } strncpy(buf, str, i); *outValue = atoi(buf); if (*outValue > (unsigned short)-1) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %u: %s must be less than %hu.\n", output, elementName, (unsigned short)-1); goto exit; } str += i; if (needTerminator || str[0] != '\0') { Bool unexpected = TRUE; for (i = 0; i < strlen(expectedTerminators); i++) { if (str[0] == expectedTerminators[i]) { unexpected = FALSE; } } if (unexpected) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %u: unexpected character '%c' after %s.\n", output, str[0], elementName); goto exit; } else { str++; } } retVal = str - element; exit: return retVal; } xXineramaScreenInfo * VMWAREParseTopologyString(ScrnInfoPtr pScrn, const char *topology, unsigned int *retNumOutputs, const char info[]) { xXineramaScreenInfo *extents = NULL; unsigned int numOutputs = 0; const char *str = topology; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Parsing %s topology: Starting...\n", info); do { unsigned int x, y, width, height; int i; i = VMWAREParseTopologyElement(pScrn, numOutputs, "width", str, "xX", TRUE, &width); if (i == -1) { goto error; } str += i; i = VMWAREParseTopologyElement(pScrn, numOutputs, "height", str, "+", TRUE, &height); if (i == -1) { goto error; } str += i; i= VMWAREParseTopologyElement(pScrn, numOutputs, "X offset", str, "+", TRUE, &x); if (i == -1) { goto error; } str += i; i = VMWAREParseTopologyElement(pScrn, numOutputs, "Y offset", str, ";", FALSE, &y); if (i == -1) { goto error; } str += i; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %u: %ux%u+%u+%u\n", numOutputs, width, height, x, y); numOutputs++; extents = realloc(extents, numOutputs * sizeof (xXineramaScreenInfo)); extents[numOutputs - 1].x_org = x; extents[numOutputs - 1].y_org = y; extents[numOutputs - 1].width = width; extents[numOutputs - 1].height = height; } while (*str != 0); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Parsing %s topology: Succeeded.\n", info); goto exit; error: xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Parsing %s topology: Failed.\n", info); free(extents); extents = NULL; numOutputs = 0; exit: *retNumOutputs = numOutputs; return extents; }