13bfa90b6Smrg/* 23bfa90b6Smrg * Copyright 2011 VMWare, Inc. 33bfa90b6Smrg * All Rights Reserved. 43bfa90b6Smrg * 53bfa90b6Smrg * Permission is hereby granted, free of charge, to any person obtaining a 63bfa90b6Smrg * copy of this software and associated documentation files (the 73bfa90b6Smrg * "Software"), to deal in the Software without restriction, including 83bfa90b6Smrg * without limitation the rights to use, copy, modify, merge, publish, 93bfa90b6Smrg * distribute, sub license, and/or sell copies of the Software, and to 103bfa90b6Smrg * permit persons to whom the Software is furnished to do so, subject to 113bfa90b6Smrg * the following conditions: 123bfa90b6Smrg * 133bfa90b6Smrg * The above copyright notice and this permission notice (including the 143bfa90b6Smrg * next paragraph) shall be included in all copies or substantial portions 153bfa90b6Smrg * of the Software. 163bfa90b6Smrg * 173bfa90b6Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 183bfa90b6Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 193bfa90b6Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 203bfa90b6Smrg * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 213bfa90b6Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 223bfa90b6Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 233bfa90b6Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 243bfa90b6Smrg * 253bfa90b6Smrg * Author: Unknown at vmware 263bfa90b6Smrg */ 273bfa90b6Smrg#ifdef HAVE_CONFIG_H 283bfa90b6Smrg#include "config.h" 293bfa90b6Smrg#endif 303bfa90b6Smrg 313bfa90b6Smrg#include <xf86.h> 323bfa90b6Smrg#include "vmware_common.h" 333bfa90b6Smrg 343bfa90b6Smrg#ifndef HAVE_XORG_SERVER_1_5_0 353bfa90b6Smrg#include <xf86_ansic.h> 363bfa90b6Smrg#include <xf86_libc.h> 373bfa90b6Smrg#endif 383bfa90b6Smrg 393bfa90b6Smrgstatic int 403bfa90b6SmrgVMWAREParseTopologyElement(ScrnInfoPtr pScrn, 413bfa90b6Smrg unsigned int output, 423bfa90b6Smrg const char *elementName, 433bfa90b6Smrg const char *element, 443bfa90b6Smrg const char *expectedTerminators, 453bfa90b6Smrg Bool needTerminator, 463bfa90b6Smrg unsigned int *outValue) 473bfa90b6Smrg{ 483bfa90b6Smrg char buf[10] = {0, }; 493bfa90b6Smrg size_t i = 0; 503bfa90b6Smrg int retVal = -1; 513bfa90b6Smrg const char *str = element; 523bfa90b6Smrg 533bfa90b6Smrg for (i = 0; str[i] >= '0' && str[i] <= '9'; i++); 543bfa90b6Smrg if (i == 0) { 553bfa90b6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %u: unable to parse %s.\n", 563bfa90b6Smrg output, elementName); 573bfa90b6Smrg goto exit; 583bfa90b6Smrg } 593bfa90b6Smrg 603bfa90b6Smrg strncpy(buf, str, i); 613bfa90b6Smrg *outValue = atoi(buf); 623bfa90b6Smrg 633bfa90b6Smrg if (*outValue > (unsigned short)-1) { 643bfa90b6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %u: %s must be less than %hu.\n", 653bfa90b6Smrg output, elementName, (unsigned short)-1); 663bfa90b6Smrg goto exit; 673bfa90b6Smrg } 683bfa90b6Smrg 693bfa90b6Smrg str += i; 703bfa90b6Smrg 713bfa90b6Smrg if (needTerminator || str[0] != '\0') { 723bfa90b6Smrg Bool unexpected = TRUE; 733bfa90b6Smrg 743bfa90b6Smrg for (i = 0; i < strlen(expectedTerminators); i++) { 753bfa90b6Smrg if (str[0] == expectedTerminators[i]) { 763bfa90b6Smrg unexpected = FALSE; 773bfa90b6Smrg } 783bfa90b6Smrg } 793bfa90b6Smrg 803bfa90b6Smrg if (unexpected) { 813bfa90b6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, 823bfa90b6Smrg "Output %u: unexpected character '%c' after %s.\n", 833bfa90b6Smrg output, str[0], elementName); 843bfa90b6Smrg goto exit; 853bfa90b6Smrg } else { 863bfa90b6Smrg str++; 873bfa90b6Smrg } 883bfa90b6Smrg } 893bfa90b6Smrg 903bfa90b6Smrg retVal = str - element; 913bfa90b6Smrg 923bfa90b6Smrg exit: 933bfa90b6Smrg return retVal; 943bfa90b6Smrg} 953bfa90b6Smrg 963bfa90b6SmrgxXineramaScreenInfo * 973bfa90b6SmrgVMWAREParseTopologyString(ScrnInfoPtr pScrn, 983bfa90b6Smrg const char *topology, 993bfa90b6Smrg unsigned int *retNumOutputs, 1003bfa90b6Smrg const char info[]) 1013bfa90b6Smrg{ 1023bfa90b6Smrg xXineramaScreenInfo *extents = NULL; 1033bfa90b6Smrg unsigned int numOutputs = 0; 1043bfa90b6Smrg const char *str = topology; 1053bfa90b6Smrg 1063bfa90b6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Parsing %s topology: Starting...\n", 1073bfa90b6Smrg info); 1083bfa90b6Smrg 1093bfa90b6Smrg do { 1103bfa90b6Smrg unsigned int x, y, width, height; 1113bfa90b6Smrg int i; 1123bfa90b6Smrg 1133bfa90b6Smrg i = VMWAREParseTopologyElement(pScrn, numOutputs, "width", str, "xX", TRUE, &width); 1143bfa90b6Smrg if (i == -1) { 1153bfa90b6Smrg goto error; 1163bfa90b6Smrg } 1173bfa90b6Smrg str += i; 1183bfa90b6Smrg 1193bfa90b6Smrg i = VMWAREParseTopologyElement(pScrn, numOutputs, "height", str, "+", TRUE, &height); 1203bfa90b6Smrg if (i == -1) { 1213bfa90b6Smrg goto error; 1223bfa90b6Smrg } 1233bfa90b6Smrg str += i; 1243bfa90b6Smrg 1253bfa90b6Smrg i= VMWAREParseTopologyElement(pScrn, numOutputs, "X offset", str, "+", TRUE, &x); 1263bfa90b6Smrg if (i == -1) { 1273bfa90b6Smrg goto error; 1283bfa90b6Smrg } 1293bfa90b6Smrg str += i; 1303bfa90b6Smrg 1313bfa90b6Smrg i = VMWAREParseTopologyElement(pScrn, numOutputs, "Y offset", str, ";", FALSE, &y); 1323bfa90b6Smrg if (i == -1) { 1333bfa90b6Smrg goto error; 1343bfa90b6Smrg } 1353bfa90b6Smrg str += i; 1363bfa90b6Smrg 1373bfa90b6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output %u: %ux%u+%u+%u\n", 1383bfa90b6Smrg numOutputs, width, height, x, y); 1393bfa90b6Smrg 1403bfa90b6Smrg numOutputs++; 1413bfa90b6Smrg extents = realloc(extents, numOutputs * sizeof (xXineramaScreenInfo)); 1423bfa90b6Smrg extents[numOutputs - 1].x_org = x; 1433bfa90b6Smrg extents[numOutputs - 1].y_org = y; 1443bfa90b6Smrg extents[numOutputs - 1].width = width; 1453bfa90b6Smrg extents[numOutputs - 1].height = height; 1463bfa90b6Smrg } while (*str != 0); 1473bfa90b6Smrg 1483bfa90b6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Parsing %s topology: Succeeded.\n", 1493bfa90b6Smrg info); 1503bfa90b6Smrg goto exit; 1513bfa90b6Smrg 1523bfa90b6Smrg error: 1533bfa90b6Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Parsing %s topology: Failed.\n", 1543bfa90b6Smrg info); 1553bfa90b6Smrg 1563bfa90b6Smrg free(extents); 1573bfa90b6Smrg extents = NULL; 1583bfa90b6Smrg numOutputs = 0; 1593bfa90b6Smrg 1603bfa90b6Smrg exit: 1613bfa90b6Smrg *retNumOutputs = numOutputs; 1623bfa90b6Smrg return extents; 1633bfa90b6Smrg} 164