⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 radeon_mergedfb.c

📁 x.org上有关ati系列显卡最新驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/* $XFree86$ *//* * Copyright 2003 Alex Deucher. * * 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 on the rights to use, copy, modify, merge, * publish, distribute, sublicense, 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 ALEX DEUCHER, OR ANY OTHER  * CONTRIBUTORS 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. */#ifdef HAVE_CONFIG_H#include "config.h"#endif/* * Authors: *   Alex Deucher <agd5f@yahoo.com> *   Based, in large part, on the sis driver by Thomas Winischhofer. */#include <string.h>#include <stdio.h>#include "xf86.h"#include "xf86Priv.h"#include "xf86Resources.h"#include "xf86_OSproc.h"#include "extnsionst.h"  	/* required */#include <X11/extensions/panoramiXproto.h>  	/* required */#include "dixstruct.h"#include "vbe.h"#include "radeon.h"#include "radeon_reg.h"#include "radeon_macros.h"#include "radeon_mergedfb.h"/* psuedo xinerama support */static unsigned char 	RADEONXineramaReqCode = 0;int 			RADEONXineramaPixWidth = 0;int 			RADEONXineramaPixHeight = 0;int 			RADEONXineramaNumScreens = 0;RADEONXineramaData	*RADEONXineramadataPtr = NULL;static int 		RADEONXineramaGeneration;Bool 		RADEONnoPanoramiXExtension = TRUE;int RADEONProcXineramaQueryVersion(ClientPtr client);int RADEONProcXineramaGetState(ClientPtr client);int RADEONProcXineramaGetScreenCount(ClientPtr client);int RADEONProcXineramaGetScreenSize(ClientPtr client);int RADEONProcXineramaIsActive(ClientPtr client);int RADEONProcXineramaQueryScreens(ClientPtr client);int RADEONSProcXineramaDispatch(ClientPtr client);static voidRADEONChooseCursorCRTC(ScrnInfoPtr pScrn1, int x, int y);/* mergedfb functions *//* Helper function for CRT2 monitor vrefresh/hsync options * (Taken from mga, sis drivers) */intRADEONStrToRanges(range *r, char *s, int max){   float num = 0.0;   int rangenum = 0;   Bool gotdash = FALSE;   Bool nextdash = FALSE;   char* strnum = NULL;   do {     switch(*s) {     case '0':     case '1':     case '2':     case '3':     case '4':     case '5':     case '6':     case '7':     case '8':     case '9':     case '.':        if(strnum == NULL) {           strnum = s;           gotdash = nextdash;           nextdash = FALSE;        }        break;     case '-':     case ' ':     case 0:        if(strnum == NULL) break;	sscanf(strnum, "%f", &num);	strnum = NULL;        if(gotdash)           r[rangenum - 1].hi = num;        else {           r[rangenum].lo = num;           r[rangenum].hi = num;           rangenum++;        }        if(*s == '-') nextdash = (rangenum != 0);        else if(rangenum >= max) return rangenum;        break;     default :        return 0;     }   } while(*(s++) != 0);   return rangenum;}/* Copy and link two modes (i, j) for merged-fb mode * (Taken from mga, sis drivers) * Copys mode i, merges j to copy of i, links the result to dest, and returns it. * Links i and j in Private record. * If dest is NULL, return value is copy of i linked to itself. * For mergedfb auto-config, we only check the dimension * against virtualX/Y, if they were user-provided. */static DisplayModePtrRADEONCopyModeNLink(ScrnInfoPtr pScrn, DisplayModePtr dest,                 DisplayModePtr i, DisplayModePtr j,		 RADEONScrn2Rel srel){    DisplayModePtr mode;    int dx = 0,dy = 0;    RADEONInfoPtr  info       = RADEONPTR(pScrn);    if(!((mode = xalloc(sizeof(DisplayModeRec))))) return dest;    memcpy(mode, i, sizeof(DisplayModeRec));    if(!((mode->Private = xalloc(sizeof(RADEONMergedDisplayModeRec))))) {       xfree(mode);       return dest;    }    ((RADEONMergedDisplayModePtr)mode->Private)->CRT1 = i;    ((RADEONMergedDisplayModePtr)mode->Private)->CRT2 = j;    ((RADEONMergedDisplayModePtr)mode->Private)->CRT2Position = srel;    mode->PrivSize = 0;    switch(srel) {    case radeonLeftOf:    case radeonRightOf:       if(!(pScrn->display->virtualX)) {          dx = i->HDisplay + j->HDisplay;       } else {          dx = min(pScrn->virtualX, i->HDisplay + j->HDisplay);       }       dx -= mode->HDisplay;       if(!(pScrn->display->virtualY)) {          dy = max(i->VDisplay, j->VDisplay);       } else {          dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));       }       dy -= mode->VDisplay;       break;    case radeonAbove:    case radeonBelow:       if(!(pScrn->display->virtualY)) {          dy = i->VDisplay + j->VDisplay;       } else {          dy = min(pScrn->virtualY, i->VDisplay + j->VDisplay);       }       dy -= mode->VDisplay;       if(!(pScrn->display->virtualX)) {          dx = max(i->HDisplay, j->HDisplay);       } else {          dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));       }       dx -= mode->HDisplay;       break;    case radeonClone:       if(!(pScrn->display->virtualX)) {          dx = max(i->HDisplay, j->HDisplay);       } else {          dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));       }       dx -= mode->HDisplay;       if(!(pScrn->display->virtualY)) {          dy = max(i->VDisplay, j->VDisplay);       } else {	  dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));       }       dy -= mode->VDisplay;       break;    }    mode->HDisplay += dx;    mode->HSyncStart += dx;    mode->HSyncEnd += dx;    mode->HTotal += dx;    mode->VDisplay += dy;    mode->VSyncStart += dy;    mode->VSyncEnd += dy;    mode->VTotal += dy;    /* This is needed for not generating negative refesh rates in xrandr with the       faked DotClock below     */    if (!(mode->VRefresh))        mode->VRefresh = mode->Clock * 1000.0 / mode->HTotal / mode->VTotal;     /* Provide a sophisticated fake DotClock in order to trick the vidmode      * extension to allow selecting among a number of modes whose merged result      * looks identical but consists of different modes for CRT1 and CRT2      */    mode->Clock = (((i->Clock >> 3) + i->HTotal) << 16) | ((j->Clock >> 2) + j->HTotal);    mode->Clock ^= ((i->VTotal << 19) | (j->VTotal << 3));    if( ((mode->HDisplay * ((pScrn->bitsPerPixel + 7) / 8) * mode->VDisplay) > 	(pScrn->videoRam * 1024)) ||        (mode->HDisplay > 8191) ||	(mode->VDisplay > 8191) ) {       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,	        "Skipped \"%s\" (%dx%d), not enough video RAM or beyond hardware specs\n",		mode->name, mode->HDisplay, mode->VDisplay);       xfree(mode->Private);       xfree(mode);       return dest;    }    if(srel != radeonClone) {       info->AtLeastOneNonClone = TRUE;    }    xf86DrvMsg(pScrn->scrnIndex, X_INFO,    	"Merged \"%s\" (%dx%d) and \"%s\" (%dx%d) to %dx%d%s\n",	i->name, i->HDisplay, i->VDisplay, j->name, j->HDisplay, j->VDisplay,	mode->HDisplay, mode->VDisplay, (srel == radeonClone) ? " (Clone)" : "");    mode->next = mode;    mode->prev = mode;    if(dest) {        mode->next = dest->next; 	/* Insert node after "dest" */        dest->next->prev = mode;        mode->prev = dest;        dest->next = mode;    }    return mode;}/* Helper function to find a mode from a given name * (Taken from mga, sis drivers) */static DisplayModePtrRADEONGetModeFromName(char* str, DisplayModePtr i){    DisplayModePtr c = i;    if(!i) return NULL;    do {       if(strcmp(str, c->name) == 0) return c;       c = c->next;    } while(c != i);    return NULL;}static DisplayModePtrRADEONFindWidestTallestMode(DisplayModePtr i, Bool tallest){    DisplayModePtr c = i, d = NULL;    int max = 0;    if(!i) return NULL;    do {       if(tallest) {          if(c->VDisplay > max) {             max = c->VDisplay;	     d = c;          }       } else {          if(c->HDisplay > max) {             max = c->HDisplay;	     d = c;          }       }       c = c->next;    } while(c != i);    return d;}static voidRADEONFindWidestTallestCommonMode(DisplayModePtr i, DisplayModePtr j, Bool tallest,				DisplayModePtr *a, DisplayModePtr *b){    DisplayModePtr c = i, d;    int max = 0;    Bool foundone;    (*a) = (*b) = NULL;    if(!i || !j) return;    do {       d = j;       foundone = FALSE;       do {	  if( (c->HDisplay == d->HDisplay) &&	      (c->VDisplay == d->VDisplay) ) {	     foundone = TRUE;	     break;	  }	  d = d->next;       } while(d != j);       if(foundone) {	  if(tallest) {	     if(c->VDisplay > max) {		max = c->VDisplay;		(*a) = c;		(*b) = d;	     }	  } else {	     if(c->HDisplay > max) {		max = c->HDisplay;		(*a) = c;		(*b) = d;	     }	  }       }       c = c->next;    } while(c != i);}static DisplayModePtrRADEONGenerateModeListFromLargestModes(ScrnInfoPtr pScrn,		    DisplayModePtr i, DisplayModePtr j,		    RADEONScrn2Rel srel){    RADEONInfoPtr  info       = RADEONPTR(pScrn);    DisplayModePtr mode1 = NULL;    DisplayModePtr mode2 = NULL;    DisplayModePtr mode3 = NULL;    DisplayModePtr mode4 = NULL;    DisplayModePtr result = NULL;    info->AtLeastOneNonClone = FALSE;    /* Now build a default list of MetaModes.     * - Non-clone: If the user enabled NonRectangular, we use the     * largest mode for each CRT1 and CRT2. If not, we use the largest     * common mode for CRT1 and CRT2 (if available). Additionally, and     * regardless if the above, we produce a clone mode consisting of     * the largest common mode (if available) in order to use DGA.     * - Clone: If the (global) CRT2Position is Clone, we use the     * largest common mode if available, otherwise the first two modes     * in each list.     */    switch(srel) {    case radeonLeftOf:    case radeonRightOf:       mode1 = RADEONFindWidestTallestMode(i, FALSE);       mode2 = RADEONFindWidestTallestMode(j, FALSE);       RADEONFindWidestTallestCommonMode(i, j, FALSE, &mode3, &mode4);       break;    case radeonAbove:    case radeonBelow:       mode1 = RADEONFindWidestTallestMode(i, TRUE);       mode2 = RADEONFindWidestTallestMode(j, TRUE);       RADEONFindWidestTallestCommonMode(i, j, TRUE, &mode3, &mode4);       break;    case radeonClone:       RADEONFindWidestTallestCommonMode(i, j, FALSE, &mode3, &mode4);       if(mode3 && mode4) {	  mode1 = mode3;	  mode2 = mode4;       } else {	  mode1 = i;	  mode2 = j;       }    }    if(srel != radeonClone) {       if(mode3 && mode4 && !info->NonRect) {	  mode1 = mode3;	  mode2 = mode2;       }    }    if(mode1 && mode2) {       result = RADEONCopyModeNLink(pScrn, result, mode1, mode2, srel);    }    if(srel != radeonClone) {       if(mode3 && mode4) {	  result = RADEONCopyModeNLink(pScrn, result, mode3, mode4, radeonClone);       }    }    return result;}/* Generate the merged-fb mode modelist * (Taken from mga, sis drivers) */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -