2602 lines
84 KiB
C
2602 lines
84 KiB
C
/* $XFree86$ */
|
|
/* $XdotOrg$ */
|
|
/*
|
|
* SiS driver utility interface & routines
|
|
*
|
|
* Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1) Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2) Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3) The name of the author may not be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* Author: Thomas Winischhofer <thomas@winischhofer.net>
|
|
*
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include "sis.h"
|
|
#define NEED_REPLIES
|
|
#define NEED_EVENTS
|
|
#include <X11/X.h>
|
|
#include "dixstruct.h"
|
|
#define _XF86MISC_SERVER_
|
|
#include <X11/extensions/xf86misc.h>
|
|
|
|
#include "sis_videostr.h"
|
|
|
|
#ifdef TWDEBUG
|
|
#define SIS_NEED_orSISIDXREG
|
|
#include "sis_regs.h"
|
|
#endif
|
|
|
|
/* Definitions for SISCTRL extension */
|
|
|
|
#define SISCTRL_PROTOCOL_NAME "SISCTRL"
|
|
|
|
#define SISCTRL_MAJOR_VERSION 0 /* current version numbers */
|
|
#define SISCTRL_MINOR_VERSION 1
|
|
|
|
#define SISCTRL_MAX_SCREENS 32 /* number of screens the ext can handle */
|
|
|
|
#define X_SiSCtrlQueryVersion 0
|
|
#define X_SiSCtrlCommand 1
|
|
|
|
#define SDC_ID 0x53495321
|
|
|
|
#define SDC_VERSION 1
|
|
|
|
#define SDC_NUM_PARM_RESULT 20
|
|
|
|
/* sdc_command */
|
|
#define SDC_CMD_GETVERSION 0x98980001
|
|
#define SDC_CMD_GETHWINFO 0x98980002
|
|
#define SDC_CMD_GETALLFLAGS 0x98980003
|
|
#define SDC_CMD_GETVBFLAGSVERSION 0x98980004
|
|
#define SDC_CMD_GETVBFLAGS 0x98980005
|
|
#define SDC_CMD_CHECKMODEFORCRT2 0x98980006
|
|
#define SDC_CMD_SETVBFLAGS 0x98980007
|
|
#define SDC_CMD_GETDETECTEDDEVICES 0x98980008
|
|
#define SDC_CMD_REDETECTCRT2DEVICES 0x98980009
|
|
#define SDC_CMD_GETCRT1STATUS 0x9898000a
|
|
#define SDC_CMD_SETCRT1STATUS 0x9898000b
|
|
#define SDC_CMD_GETSDFLAGS 0x9898000c
|
|
#define SDC_CMD_GETSD2FLAGS 0x9898000d
|
|
#define SDC_CMD_GETLOCKSTATUS 0x9898000e
|
|
#define SDC_CMD_SETLOCKSTATUS 0x9898000f
|
|
#define SDC_CMD_GETTVANTIFLICKER 0x98980010
|
|
#define SDC_CMD_SETTVANTIFLICKER 0x98980011
|
|
#define SDC_CMD_GETTVSATURATION 0x98980012
|
|
#define SDC_CMD_SETTVSATURATION 0x98980013
|
|
#define SDC_CMD_GETTVEDGEENHANCE 0x98980014
|
|
#define SDC_CMD_SETTVEDGEENHANCE 0x98980015
|
|
#define SDC_CMD_GETTVCFILTER 0x98980016
|
|
#define SDC_CMD_SETTVCFILTER 0x98980017
|
|
#define SDC_CMD_GETTVYFILTER 0x98980018
|
|
#define SDC_CMD_SETTVYFILTER 0x98980019
|
|
#define SDC_CMD_GETTVCOLORCALIB 0x9898001a
|
|
#define SDC_CMD_SETTVCOLORCALIB 0x9898001b
|
|
#define SDC_CMD_GETTVCHCONTRAST 0x9898001c
|
|
#define SDC_CMD_SETTVCHCONTRAST 0x9898001d
|
|
#define SDC_CMD_GETTVCHTEXTENHANCE 0x9898001e
|
|
#define SDC_CMD_SETTVCHTEXTENHANCE 0x9898001f
|
|
#define SDC_CMD_GETTVCHCHROMAFLICKERFILTER 0x98980020
|
|
#define SDC_CMD_SETTVCHCHROMAFLICKERFILTER 0x98980021
|
|
#define SDC_CMD_GETTVCHLUMAFLICKERFILTER 0x98980022
|
|
#define SDC_CMD_SETTVCHLUMAFLICKERFILTER 0x98980023
|
|
#define SDC_CMD_GETTVCHCVBSCOLOR 0x98980024
|
|
#define SDC_CMD_SETTVCHCVBSCOLOR 0x98980025
|
|
#define SDC_CMD_GETCHTVOVERSCAN 0x98980026
|
|
#define SDC_CMD_SETCHTVOVERSCAN 0x98980027
|
|
#define SDC_CMD_GETGAMMASTATUS 0x98980028
|
|
#define SDC_CMD_SETGAMMASTATUS 0x98980029
|
|
#define SDC_CMD_GETTVXSCALE 0x9898002a
|
|
#define SDC_CMD_SETTVXSCALE 0x9898002b
|
|
#define SDC_CMD_GETTVYSCALE 0x9898002c
|
|
#define SDC_CMD_SETTVYSCALE 0x9898002d
|
|
#define SDC_CMD_GETSCREENSIZE 0x9898002e
|
|
#define SDC_CMD_GETGAMMABRIGHTNESS 0x9898002f
|
|
#define SDC_CMD_SETGAMMABRIGHTNESS 0x98980030
|
|
#define SDC_CMD_GETGAMMABRIGHTNESS2 0x98980031
|
|
#define SDC_CMD_SETGAMMABRIGHTNESS2 0x98980032
|
|
#define SDC_CMD_GETGETGAMMACRT2 0x98980033
|
|
#define SDC_CMD_SETGETGAMMACRT2 0x98980034
|
|
#define SDC_CMD_GETHWCURSORSTATUS 0x98980035
|
|
#define SDC_CMD_SETHWCURSORSTATUS 0x98980036
|
|
#define SDC_CMD_GETPANELMODE 0x98980037
|
|
#define SDC_CMD_SETPANELMODE 0x98980038
|
|
#define SDC_CMD_GETMERGEDMODEDETAILS 0x98980039
|
|
#define SDC_CMD_GETDEVICENAME 0x9898003a
|
|
#define SDC_CMD_GETMONITORNAME 0x9898003b
|
|
#define SDC_CMD_GETDEVICENAME2 0x9898003c
|
|
#define SDC_CMD_GETMONITORNAME2 0x9898003d
|
|
#define SDC_CMD_SETXVBRIGHTNESS 0x9898003e
|
|
#define SDC_CMD_GETXVBRIGHTNESS 0x9898003f
|
|
#define SDC_CMD_SETXVCONTRAST 0x98980040
|
|
#define SDC_CMD_GETXVCONTRAST 0x98980041
|
|
#define SDC_CMD_SETXVHUE 0x98980042
|
|
#define SDC_CMD_GETXVHUE 0x98980043
|
|
#define SDC_CMD_SETXVSATURATION 0x98980044
|
|
#define SDC_CMD_GETXVSATURATION 0x98980045
|
|
#define SDC_CMD_SETXVGAMMA 0x98980046
|
|
#define SDC_CMD_GETXVGAMMA 0x98980047
|
|
#define SDC_CMD_SETXVCOLORKEY 0x98980048
|
|
#define SDC_CMD_GETXVCOLORKEY 0x98980049
|
|
#define SDC_CMD_SETXVAUTOPAINTCOLORKEY 0x9898004a
|
|
#define SDC_CMD_GETXVAUTOPAINTCOLORKEY 0x9898004b
|
|
#define SDC_CMD_SETXVDEFAULTS 0x9898004c
|
|
#define SDC_CMD_SETXVDISABLEGFX 0x9898004d
|
|
#define SDC_CMD_GETXVDISABLEGFX 0x9898004e
|
|
#define SDC_CMD_SETXVDISABLEGFXLR 0x9898004f
|
|
#define SDC_CMD_GETXVDISABLEGFXLR 0x98980050
|
|
#define SDC_CMD_SETXVSWITCHCRT 0x98980051
|
|
#define SDC_CMD_GETXVSWITCHCRT 0x98980052
|
|
#define SDC_CMD_GETTVXPOS 0x98980053
|
|
#define SDC_CMD_SETTVXPOS 0x98980054
|
|
#define SDC_CMD_GETTVYPOS 0x98980055
|
|
#define SDC_CMD_SETTVYPOS 0x98980056
|
|
#define SDC_CMD_SETXVDEINT 0x98980057
|
|
#define SDC_CMD_GETXVDEINT 0x98980058
|
|
#define SDC_CMD_GETMONGAMMACRT1 0x98980059
|
|
#define SDC_CMD_GETMONGAMMACRT2 0x9898005a
|
|
#define SDC_CMD_LOGQUIET 0x9898005b
|
|
#define SDC_CMD_GETNEWGAMMABRICON 0x9898005c
|
|
#define SDC_CMD_SETNEWGAMMABRICON 0x9898005d
|
|
#define SDC_CMD_GETNEWGAMMABRICON2 0x9898005e
|
|
#define SDC_CMD_SETNEWGAMMABRICON2 0x9898005f
|
|
#define SDC_CMD_GETGETNEWGAMMACRT2 0x98980060
|
|
#define SDC_CMD_SETGETNEWGAMMACRT2 0x98980061
|
|
#define SDC_CMD_NEWSETVBFLAGS 0x98980062
|
|
#define SDC_CMD_GETCRT1SATGAIN 0x98980063
|
|
#define SDC_CMD_SETCRT1SATGAIN 0x98980064
|
|
#define SDC_CMD_GETCRT2SATGAIN 0x98980065
|
|
#define SDC_CMD_SETCRT2SATGAIN 0x98980066
|
|
/* more to come, adapt MAXCOMMAND! */
|
|
#define SDC_MAXCOMMAND SDC_CMD_SETCRT2SATGAIN
|
|
|
|
/* in result_header */
|
|
#define SDC_RESULT_OK 0x66670000
|
|
#define SDC_RESULT_UNDEFCMD 0x66670001
|
|
#define SDC_RESULT_NOPERM 0x66670002
|
|
#define SDC_RESULT_INVAL 0x66670003
|
|
#define SDC_RESULT_MESSAGEERROR 0x66670004 /* Client side only */
|
|
#define SDC_RESULT_NOEXTENSION 0x66670005 /* Client side only */
|
|
|
|
/* For SDC_CMD_GETHWINFO */
|
|
#define SDC_BUS_TYPE_PCI 0
|
|
#define SDC_BUS_TYPE_AGP 1
|
|
#define SDC_BUS_TYPE_PCIE 2
|
|
#define SDC_BUS_TYPE_USB 3
|
|
|
|
/* For SDC_CMD_GETMERGEDMODEDETAILS */
|
|
#define SDC_MMODE_POS_ERROR 0
|
|
#define SDC_MMODE_POS_LEFTOF 1
|
|
#define SDC_MMODE_POS_RIGHTOF 2
|
|
#define SDC_MMODE_POS_ABOVE 3
|
|
#define SDC_MMODE_POS_BELOW 4
|
|
#define SDC_MMODE_POS_CLONE 5
|
|
|
|
typedef struct _SiSCtrlQueryVersion {
|
|
CARD8 reqType; /* always SiSCtrlReqCode */
|
|
CARD8 SiSCtrlReqType; /* always X_SiSCtrlQueryVersion */
|
|
CARD16 length B16;
|
|
} xSiSCtrlQueryVersionReq;
|
|
#define sz_xSiSCtrlQueryVersionReq 4
|
|
|
|
typedef struct {
|
|
BYTE type; /* X_Reply */
|
|
BOOL pad1;
|
|
CARD16 sequenceNumber B16;
|
|
CARD32 length B32;
|
|
CARD16 majorVersion B16; /* major version of SISCTRL */
|
|
CARD16 minorVersion B16; /* minor version of SISCTRL */
|
|
CARD32 pad2 B32;
|
|
CARD32 pad3 B32;
|
|
CARD32 pad4 B32;
|
|
CARD32 pad5 B32;
|
|
CARD32 pad6 B32;
|
|
} xSiSCtrlQueryVersionReply;
|
|
#define sz_xSiSCtrlQueryVersionReply 32
|
|
|
|
typedef struct {
|
|
CARD8 reqType; /* always SiSCtrlReqCode */
|
|
CARD8 SiSCtrlReqType; /* always SiSCtrl_SiSCtrlCommand */
|
|
CARD16 length B16;
|
|
CARD32 pad1 B32;
|
|
CARD32 screen;
|
|
CARD32 sdc_id;
|
|
CARD32 sdc_chksum;
|
|
CARD32 sdc_command;
|
|
CARD32 sdc_parm[SDC_NUM_PARM_RESULT];
|
|
CARD32 sdc_result_header;
|
|
CARD32 sdc_result[SDC_NUM_PARM_RESULT];
|
|
char sdc_buffer[32];
|
|
} xSiSCtrlCommandReq;
|
|
#define sz_xSiSCtrlCommandReq (28 + (SDC_NUM_PARM_RESULT * 4 * 2) + 32)
|
|
|
|
typedef struct {
|
|
BYTE type; /* X_Reply */
|
|
BOOL pad1;
|
|
CARD16 sequenceNumber B16;
|
|
CARD32 length B32;
|
|
CARD32 screen;
|
|
CARD32 sdc_id;
|
|
CARD32 sdc_chksum;
|
|
CARD32 sdc_command;
|
|
CARD32 sdc_parm[SDC_NUM_PARM_RESULT];
|
|
CARD32 sdc_result_header;
|
|
CARD32 sdc_result[SDC_NUM_PARM_RESULT];
|
|
char sdc_buffer[32];
|
|
} xSiSCtrlCommandReply;
|
|
#define sz_xSiSCtrlCommandReply (28 + (SDC_NUM_PARM_RESULT * 4 * 2) + 32)
|
|
|
|
typedef struct {
|
|
unsigned int maxscreens; /* Max number of entries = SISCTRL_MAX_SCREENS*/
|
|
unsigned int version_major; /* Extension major version */
|
|
unsigned int version_minor; /* Extension minor version */
|
|
int (*HandleSiSDirectCommand[SISCTRL_MAX_SCREENS])(xSiSCtrlCommandReply *);
|
|
} xSiSCtrlScreenTable;
|
|
|
|
#ifdef X_XF86MiscPassMessage
|
|
int SISHandleMessage(int scrnIndex, const char *msgtype, const char *msgval, char **retmsg);
|
|
#endif
|
|
void SiSCtrlExtInit(ScrnInfoPtr pScrn);
|
|
void SiSCtrlExtUnregister(SISPtr pSiS, int index);
|
|
|
|
#ifdef XV_SD_DEPRECATED
|
|
int SISSetPortUtilAttribute(ScrnInfoPtr pScrn, Atom attribute,
|
|
INT32 value, SISPortPrivPtr pPriv);
|
|
int SISGetPortUtilAttribute(ScrnInfoPtr pScrn, Atom attribute,
|
|
INT32 *value, SISPortPrivPtr pPriv);
|
|
#endif
|
|
|
|
extern Bool SISRedetectCRT2Type(ScrnInfoPtr pScrn);
|
|
extern UShort SiS_CheckModeCRT1(ScrnInfoPtr pScrn, DisplayModePtr mode,
|
|
unsigned int VBFlags, Bool hcm);
|
|
extern UShort SiS_CheckModeCRT2(ScrnInfoPtr pScrn, DisplayModePtr mode,
|
|
unsigned int VBFlags, Bool hcm);
|
|
extern void SISAdjustFrame(int scrnIndex, int x, int y, int flags);
|
|
extern float SiSCalcVRate(DisplayModePtr mode);
|
|
extern void SiS_UpdateGammaCRT2(ScrnInfoPtr pScrn);
|
|
#ifdef SISGAMMARAMP
|
|
extern void SISCalculateGammaRamp(ScreenPtr pScreen, ScrnInfoPtr pScrn);
|
|
#endif
|
|
|
|
extern void SISSetPortDefaults(ScrnInfoPtr pScrn, SISPortPrivPtr pPriv);
|
|
extern void SISUpdateVideoParms(SISPtr pSiS, SISPortPrivPtr pPriv);
|
|
extern void SiSUpdateXvGamma(SISPtr pSiS, SISPortPrivPtr pPriv);
|
|
|
|
/***********************************
|
|
* Low-level routines *
|
|
***********************************/
|
|
|
|
static Bool
|
|
SISSwitchCRT1Status(ScrnInfoPtr pScrn, int onoff, Bool quiet)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
DisplayModePtr mode = pScrn->currentMode;
|
|
ULong vbflags = pSiS->VBFlags;
|
|
ULong vbflags3 = pSiS->VBFlags3;
|
|
int crt1off;
|
|
|
|
/* onoff: 0=OFF, 1=ON(VGA), 2=ON(LCDA) */
|
|
|
|
/* Switching to LCDA will disable CRT2 if previously LCD or VGA,
|
|
* unless on a dual-vb setup
|
|
*/
|
|
|
|
/* For usability reasons, the user should not simply "lose" one
|
|
* of his output devices in MergedFB mode. Therefore, a switch
|
|
* which might lead to this situation will not be performed in
|
|
* MergedFB mode. (For example: If CRT2 is either LCD or VGA,
|
|
* don't let the user switch to LCD-via-CRT1 mode, because he
|
|
* would lose one output device since LCD-via-CRT1 is only
|
|
* supported together with TV, not any other CRT2 type.)
|
|
* In Non-MergedFB mode, losing one output device is not
|
|
* considered that harmful.
|
|
* Update: We let the user switch off a device if currently
|
|
* a "clone" mode is active. Same for switching CRT1 to LCD
|
|
* while CRT2 is LCD or VGA.
|
|
*/
|
|
|
|
/* Do NOT use this to switch from CRT1_LCDA to CRT2_LCD */
|
|
|
|
/* Only on 300 and 315/330/340 series */
|
|
if(pSiS->VGAEngine != SIS_300_VGA &&
|
|
pSiS->VGAEngine != SIS_315_VGA) return FALSE;
|
|
|
|
/* Off only if at least one CRT2 device is active */
|
|
if((!onoff) && (!(vbflags & CRT2_ENABLE))) return FALSE;
|
|
|
|
#ifdef SISDUALHEAD
|
|
if(pSiS->DualHeadMode) return FALSE;
|
|
#endif
|
|
|
|
/* Can't switch to LCDA if not supported (duh!) */
|
|
if(!(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTLCDA)) {
|
|
if(onoff == 2) {
|
|
if(!quiet) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"LCD-via-CRT1 not supported by hardware or no panel detected\n");
|
|
}
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
#ifdef SISMERGED
|
|
if(pSiS->MergedFB) {
|
|
if(((SiSMergedDisplayModePtr)mode->Private)->CRT2Position != sisClone) {
|
|
if(!onoff) {
|
|
if(!quiet) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"CRT1 can't be switched off in MergedFB mode unless a clone mode is active\n");
|
|
}
|
|
return FALSE;
|
|
} else if(onoff == 2) {
|
|
if(!(pSiS->SiS_SD3_Flags & SiS_SD3_SUPPORTDUALDVI)) {
|
|
if(vbflags & (CRT2_LCD|CRT2_VGA)) {
|
|
if(!quiet) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"CRT1 type can only be VGA while CRT2 is LCD or VGA\n");
|
|
}
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(mode->Private) {
|
|
mode = ((SiSMergedDisplayModePtr)mode->Private)->CRT1;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
vbflags &= ~(DISPTYPE_CRT1 | SINGLE_MODE | MIRROR_MODE | CRT1_LCDA);
|
|
vbflags3 &= ~(VB3_CRT1_TV | VB3_CRT1_LCD | VB3_CRT1_VGA);
|
|
crt1off = 1;
|
|
if(onoff > 0) {
|
|
vbflags |= DISPTYPE_CRT1;
|
|
crt1off = 0;
|
|
if(onoff == 2) {
|
|
vbflags |= CRT1_LCDA;
|
|
vbflags3 |= VB3_CRT1_LCD;
|
|
if(!(pSiS->SiS_SD3_Flags & SiS_SD3_SUPPORTDUALDVI)) {
|
|
vbflags &= ~(CRT2_LCD|CRT2_VGA);
|
|
}
|
|
} else {
|
|
vbflags3 |= VB3_CRT1_VGA;
|
|
}
|
|
/* Remember: Dualhead not supported */
|
|
if(vbflags & CRT2_ENABLE) vbflags |= MIRROR_MODE;
|
|
else vbflags |= SINGLE_MODE;
|
|
} else {
|
|
vbflags |= SINGLE_MODE;
|
|
}
|
|
|
|
if(vbflags & CRT1_LCDA) {
|
|
if(SiS_CheckModeCRT1(pScrn, mode, vbflags, pSiS->HaveCustomModes) < 0x14) {
|
|
if(!quiet) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"Current mode not suitable for LCD-via-CRT1\n");
|
|
}
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
pSiS->CRT1off = crt1off;
|
|
pSiS->VBFlags = pSiS->VBFlags_backup = vbflags;
|
|
pSiS->VBFlags3 = pSiS->VBFlags_backup3 = vbflags3;
|
|
|
|
/* Sync the accelerators */
|
|
(*pSiS->SyncAccel)(pScrn);
|
|
|
|
pSiS->skipswitchcheck = TRUE;
|
|
if(!(pScrn->SwitchMode(pScrn->scrnIndex, pScrn->currentMode, 0))) {
|
|
pSiS->skipswitchcheck = FALSE;
|
|
return FALSE;
|
|
}
|
|
pSiS->skipswitchcheck = FALSE;
|
|
SISAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
|
|
return TRUE;
|
|
}
|
|
|
|
static Bool
|
|
SISRedetectCRT2Devices(ScrnInfoPtr pScrn)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
|
|
if((pSiS->VGAEngine != SIS_300_VGA) && (pSiS->VGAEngine != SIS_315_VGA)) {
|
|
return FALSE;
|
|
}
|
|
|
|
#ifdef SISDUALHEAD
|
|
if(pSiS->DualHeadMode) return FALSE;
|
|
#endif
|
|
|
|
/* Sync the accelerators */
|
|
(*pSiS->SyncAccel)(pScrn);
|
|
|
|
if(SISRedetectCRT2Type(pScrn)) {
|
|
/* If this returns TRUE, we need to reset the display mode */
|
|
/* Sync the accelerators */
|
|
(*pSiS->SyncAccel)(pScrn);
|
|
pSiS->skipswitchcheck = TRUE;
|
|
if(!(pScrn->SwitchMode(pScrn->scrnIndex, pScrn->currentMode, 0))) {
|
|
pSiS->skipswitchcheck = FALSE;
|
|
return FALSE;
|
|
}
|
|
pSiS->skipswitchcheck = FALSE;
|
|
SISAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static Bool
|
|
SISSwitchCRT2Type(ScrnInfoPtr pScrn, ULong newvbflags, Bool quiet)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
Bool hcm = pSiS->HaveCustomModes;
|
|
DisplayModePtr mode = pScrn->currentMode;
|
|
|
|
/* Do NOT use this to switch from CRT2_LCD to CRT1_LCDA */
|
|
|
|
/* Switching CRT2 to LCD or VGA will switch CRT1 to VGA if
|
|
* previously LCD-via-CRT1
|
|
*/
|
|
|
|
/* For usability reasons, the user should not simply "lose" one
|
|
* of his output devices in MergedFB mode. Therefore, a switch
|
|
* which might lead to this situation will not be performed in
|
|
* MergedFB mode. (For example: If CRT1 is LCD-via-CRT1, don't
|
|
* let the user switch CRT2 to LCD or VGA mode, because he
|
|
* would lose one output device since LCD-via-CRT1 is only
|
|
* supported together with TV, not any other CRT2 type.)
|
|
* In Non-MergedFB mode, losing one output device is not
|
|
* considered that harmful.
|
|
* Update: We allow this if currently a "clone" display mode
|
|
* is active.
|
|
*/
|
|
|
|
/* Only on 300 and 315/330/340 series */
|
|
if(pSiS->VGAEngine != SIS_300_VGA &&
|
|
pSiS->VGAEngine != SIS_315_VGA) return FALSE;
|
|
|
|
/* Only if there is a video bridge */
|
|
if(!(pSiS->VBFlags2 & VB2_VIDEOBRIDGE)) return FALSE;
|
|
|
|
#ifdef SISDUALHEAD
|
|
if(pSiS->DualHeadMode) return FALSE;
|
|
#endif
|
|
|
|
#define SiS_NewVBMask (CRT2_ENABLE|CRT1_LCDA|TV_PAL|TV_NTSC|TV_PALM|TV_PALN|TV_NTSCJ| \
|
|
TV_AVIDEO|TV_SVIDEO|TV_SCART|TV_HIVISION|TV_YPBPR|TV_YPBPRALL|\
|
|
TV_YPBPRAR)
|
|
|
|
newvbflags &= SiS_NewVBMask;
|
|
newvbflags |= pSiS->VBFlags & ~SiS_NewVBMask;
|
|
|
|
if(!(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTLCDA)) {
|
|
newvbflags &= ~CRT1_LCDA;
|
|
}
|
|
if(!(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTHIVISION)) {
|
|
newvbflags &= ~TV_HIVISION;
|
|
}
|
|
if(!(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTYPBPR)) {
|
|
newvbflags &= ~TV_YPBPR;
|
|
}
|
|
|
|
#ifdef SISMERGED
|
|
if(pSiS->MergedFB) {
|
|
if((mode->Private) &&
|
|
((SiSMergedDisplayModePtr)mode->Private)->CRT2Position != sisClone) {
|
|
if(!(newvbflags & CRT2_ENABLE)) {
|
|
if(!quiet) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"CRT2 can't be switched off in MergedFB mode unless a clone mode is active\n");
|
|
}
|
|
return FALSE;
|
|
}
|
|
if(!(pSiS->SiS_SD3_Flags & SiS_SD3_SUPPORTDUALDVI)) {
|
|
if((newvbflags & (CRT2_LCD|CRT2_VGA)) && (newvbflags & CRT1_LCDA)) {
|
|
if(!quiet) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"CRT2 type can only be TV while in LCD-via-CRT1 mode\n");
|
|
}
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
hcm = pSiS->HaveCustomModes2;
|
|
if(mode->Private) {
|
|
mode = ((SiSMergedDisplayModePtr)mode->Private)->CRT2;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if((!(newvbflags & CRT2_ENABLE)) && (!newvbflags & DISPTYPE_CRT1)) {
|
|
if(!quiet) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"CRT2 can't be switched off while CRT1 is off\n");
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/* CRT2_LCD and CRT2_VGA overrule LCDA (in non-MergedFB mode) */
|
|
if(!(pSiS->SiS_SD3_Flags & SiS_SD3_SUPPORTDUALDVI)) {
|
|
if(newvbflags & (CRT2_LCD|CRT2_VGA)) {
|
|
newvbflags &= ~CRT1_LCDA;
|
|
}
|
|
}
|
|
|
|
/* Check if the current mode is suitable for desired output device (if any) */
|
|
if(SiS_CheckModeCRT2(pScrn, mode, newvbflags, hcm) < 0x14) {
|
|
if(!quiet) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"Current mode not suitable for desired CRT2 output device\n");
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/* Remember: Dualhead not supported */
|
|
newvbflags &= ~(SINGLE_MODE | MIRROR_MODE);
|
|
if((newvbflags & DISPTYPE_CRT1) && (newvbflags & CRT2_ENABLE)) {
|
|
newvbflags |= MIRROR_MODE;
|
|
} else {
|
|
newvbflags |= SINGLE_MODE;
|
|
}
|
|
|
|
/* Sync the accelerators */
|
|
(*pSiS->SyncAccel)(pScrn);
|
|
|
|
pSiS->VBFlags = pSiS->VBFlags_backup = newvbflags;
|
|
|
|
pSiS->skipswitchcheck = TRUE;
|
|
if(!(pScrn->SwitchMode(pScrn->scrnIndex, pScrn->currentMode, 0))) {
|
|
pSiS->skipswitchcheck = FALSE;
|
|
return FALSE;
|
|
}
|
|
pSiS->skipswitchcheck = FALSE;
|
|
SISAdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
|
|
return TRUE;
|
|
}
|
|
|
|
static Bool
|
|
SISSwitchOutputType(ScrnInfoPtr pScrn, ULong newvbflags, ULong newvbflags3,
|
|
ULong newvbflags4, Bool quiet)
|
|
{
|
|
/* For future use */
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static ULong
|
|
SiSCondToVBFlags(UShort cond, ULong GivenVBFlags)
|
|
{
|
|
ULong vbflags = GivenVBFlags;
|
|
|
|
/* No special treatment for NTSC-J here; conditions equal NTSC */
|
|
if(cond) {
|
|
vbflags &= ~(CRT2_ENABLE | CRT1_LCDA | TV_STANDARD | TV_INTERFACE);
|
|
if((cond & SiS_CF2_TYPEMASK) == SiS_CF2_LCD) {
|
|
vbflags |= CRT2_LCD;
|
|
} else if((cond & SiS_CF2_TYPEMASK) == SiS_CF2_TV) {
|
|
vbflags |= (CRT2_TV | TV_SVIDEO);
|
|
if(cond & SiS_CF2_TVPAL) vbflags |= TV_PAL;
|
|
else if(cond & SiS_CF2_TVPALM) vbflags |= (TV_PAL | TV_PALM);
|
|
else if(cond & SiS_CF2_TVPALN) vbflags |= (TV_PAL | TV_PALN);
|
|
else if(cond & SiS_CF2_TVNTSC) vbflags |= TV_NTSC;
|
|
} else if((cond & SiS_CF2_TYPEMASK) == SiS_CF2_TVSPECIAL) {
|
|
vbflags |= CRT2_TV;
|
|
if((cond & SiS_CF2_TVSPECMASK) == SiS_CF2_TVHIVISION)
|
|
vbflags |= TV_HIVISION;
|
|
else if((cond & SiS_CF2_TVSPECMASK) == SiS_CF2_TVYPBPR525I)
|
|
vbflags |= (TV_YPBPR | TV_YPBPR525I);
|
|
else if((cond & SiS_CF2_TVSPECMASK) == SiS_CF2_TVYPBPR525P)
|
|
vbflags |= (TV_YPBPR | TV_YPBPR525P);
|
|
else if((cond & SiS_CF2_TVSPECMASK) == SiS_CF2_TVYPBPR625I)
|
|
vbflags |= (TV_YPBPR | TV_YPBPR625I);
|
|
else if((cond & SiS_CF2_TVSPECMASK) == SiS_CF2_TVYPBPR625P)
|
|
vbflags |= (TV_YPBPR | TV_YPBPR625P);
|
|
else if((cond & SiS_CF2_TVSPECMASK) == SiS_CF2_TVYPBPR750P)
|
|
vbflags |= (TV_YPBPR | TV_YPBPR750P);
|
|
else if((cond & SiS_CF2_TVSPECMASK) == SiS_CF2_TVYPBPR1080I)
|
|
vbflags |= (TV_YPBPR | TV_YPBPR1080I);
|
|
} else if((cond & SiS_CF2_TYPEMASK) == SiS_CF2_VGA2) {
|
|
vbflags |= CRT2_VGA;
|
|
} else if((cond & SiS_CF2_TYPEMASK) == SiS_CF2_CRT1LCDA) {
|
|
vbflags |= CRT1_LCDA;
|
|
}
|
|
}
|
|
return(vbflags);
|
|
}
|
|
|
|
static int
|
|
SISCheckModeForCRT2Type(ScrnInfoPtr pScrn, DisplayModePtr mode, ULong vbflags, UShort cond, Bool quiet)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
DisplayModePtr mastermode;
|
|
Bool hcm = pSiS->HaveCustomModes;
|
|
int result = 0;
|
|
|
|
mastermode = mode;
|
|
|
|
#ifdef SISDUALHEAD
|
|
if((!pSiS->DualHeadMode) || (!pSiS->SecondHead)) {
|
|
#endif
|
|
|
|
if(vbflags & CRT2_ENABLE) {
|
|
|
|
#ifdef SISMERGED
|
|
if(pSiS->MergedFB) {
|
|
hcm = pSiS->HaveCustomModes2;
|
|
if(mode->Private) {
|
|
mode = ((SiSMergedDisplayModePtr)mode->Private)->CRT2;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/* For RandR */
|
|
if((mode->HDisplay > pScrn->virtualX) || (mode->VDisplay > pScrn->virtualY)) {
|
|
if(!quiet) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"Desired mode too large for current screen size\n");
|
|
}
|
|
result |= 0x02;
|
|
}
|
|
|
|
/* Check if the desired mode is suitable for current CRT2 output device */
|
|
if(SiS_CheckModeCRT2(pScrn, mode, vbflags, hcm) < 0x14) {
|
|
if((!cond) && (!quiet)) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"Desired mode not suitable for current CRT2 output device\n");
|
|
}
|
|
result |= 0x01;
|
|
}
|
|
|
|
}
|
|
|
|
#ifdef SISDUALHEAD
|
|
}
|
|
#endif
|
|
|
|
mode = mastermode;
|
|
|
|
#ifdef SISDUALHEAD
|
|
if((!pSiS->DualHeadMode) || (pSiS->SecondHead)) {
|
|
#endif
|
|
|
|
if(vbflags & CRT1_LCDA) {
|
|
|
|
#ifdef SISMERGED
|
|
if(pSiS->MergedFB) {
|
|
hcm = pSiS->HaveCustomModes;
|
|
if(mode->Private) {
|
|
mode = ((SiSMergedDisplayModePtr)mode->Private)->CRT1;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/* For RandR */
|
|
if((mode->HDisplay > pScrn->virtualX) || (mode->VDisplay > pScrn->virtualY)) {
|
|
if(!quiet) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"Desired mode too large for current screen size\n");
|
|
}
|
|
result |= 0x02;
|
|
}
|
|
|
|
/* Check if the desired mode is suitable for current CRT1 output device */
|
|
if(SiS_CheckModeCRT1(pScrn, mode, vbflags, hcm) < 0x14) {
|
|
if((!cond) && (!quiet)) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"Desired mode not suitable for current CRT1 output device\n");
|
|
}
|
|
result |= 0x01;
|
|
}
|
|
|
|
}
|
|
|
|
#ifdef SISDUALHEAD
|
|
}
|
|
#endif
|
|
|
|
return result;
|
|
}
|
|
|
|
#ifdef XV_SD_DEPRECATED
|
|
static int
|
|
SISCheckModeIndexForCRT2Type(ScrnInfoPtr pScrn, UShort cond, UShort index, Bool quiet)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
DisplayModePtr mode = pScrn->modes;
|
|
ULong vbflags;
|
|
int i;
|
|
|
|
/* Not only CRT2, but also LCDA */
|
|
|
|
/* returns 0 if mode ok,
|
|
* 0x01 if mode not ok for CRT2 device,
|
|
* 0x02 if mode too large for current root window
|
|
* or combinations thereof
|
|
*/
|
|
|
|
vbflags = SiSCondToVBFlags(cond, pSiS->VBFlags);
|
|
|
|
/* Find mode of given index */
|
|
if(index) {
|
|
for(i = 0; i < index; i++) {
|
|
if(!mode) return 0x03;
|
|
mode = mode->next;
|
|
}
|
|
}
|
|
|
|
return(SISCheckModeForCRT2Type(pScrn, mode, vbflags, cond, quiet));
|
|
}
|
|
#endif
|
|
|
|
static DisplayModePtr
|
|
sisFindModeFromTiming(ScrnInfoPtr pScrn, UShort hdisplay,
|
|
UShort vdisplay, UShort htotal, UShort vtotal,
|
|
UShort hsyncstart, UShort hsyncend, UShort vsyncstart,
|
|
UShort vsyncend, int clock)
|
|
{
|
|
DisplayModePtr mode = pScrn->modes, pmode = pScrn->modes;
|
|
Bool found = FALSE;
|
|
|
|
do {
|
|
if( (mode->HDisplay == hdisplay) &&
|
|
(mode->VDisplay == vdisplay) &&
|
|
(mode->HTotal == htotal) &&
|
|
(mode->VTotal == vtotal) &&
|
|
(mode->HSyncStart == hsyncstart) &&
|
|
(mode->VSyncStart == vsyncstart) &&
|
|
(mode->HSyncEnd == hsyncend) &&
|
|
(mode->VSyncEnd == vsyncend) &&
|
|
(mode->Clock == clock) ) {
|
|
found = TRUE;
|
|
break;
|
|
}
|
|
mode = mode->next;
|
|
} while((mode) && (mode != pmode));
|
|
|
|
if(found) return mode;
|
|
else return NULL;
|
|
}
|
|
|
|
static int
|
|
SISCheckModeTimingForCRT2Type(ScrnInfoPtr pScrn, UShort cond, UShort hdisplay,
|
|
UShort vdisplay, UShort htotal, UShort vtotal,
|
|
UShort hsyncstart, UShort hsyncend, UShort vsyncstart,
|
|
UShort vsyncend, int clock, Bool quiet)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
DisplayModePtr mode;
|
|
ULong vbflags;
|
|
|
|
/* Not only CRT2, but also LCDA */
|
|
|
|
/* returns 0 if mode ok,
|
|
* 0x01 if mode not ok for CRT2 device,
|
|
* 0x02 if mode too large for current root window
|
|
* or combinations thereof
|
|
*/
|
|
|
|
vbflags = SiSCondToVBFlags(cond, pSiS->VBFlags);
|
|
|
|
/* Find mode with given timing */
|
|
mode = sisFindModeFromTiming(pScrn, hdisplay, vdisplay, htotal, vtotal,
|
|
hsyncstart, hsyncend, vsyncstart, vsyncend,
|
|
clock);
|
|
if(!mode) return 0x03;
|
|
|
|
return(SISCheckModeForCRT2Type(pScrn, mode, vbflags, cond, quiet));
|
|
}
|
|
|
|
#ifdef SISMERGED
|
|
static void
|
|
SISGetMergedModeDetails(ScrnInfoPtr pScrn,
|
|
int hd, int vd, int ht, int vt, int hss, int hse, int vss, int vse, int clk,
|
|
unsigned int *pos, unsigned int *crt1x, unsigned int *crt1y,
|
|
unsigned int *crt1clk, unsigned int *crt2x, unsigned int *crt2y,
|
|
unsigned int *crt2clk)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
DisplayModePtr mode, tmode;
|
|
|
|
if(!pSiS->MergedFB) {
|
|
*pos = SDC_MMODE_POS_ERROR;
|
|
return;
|
|
}
|
|
|
|
/* Find mode with given timing */
|
|
mode = sisFindModeFromTiming(pScrn, hd, vd, ht, vt, hss, hse, vss, vse, clk);
|
|
if(!mode) {
|
|
*pos = SDC_MMODE_POS_ERROR;
|
|
return;
|
|
}
|
|
|
|
switch(((SiSMergedDisplayModePtr)mode->Private)->CRT2Position) {
|
|
case sisLeftOf: *pos = SDC_MMODE_POS_LEFTOF; break;
|
|
case sisRightOf: *pos = SDC_MMODE_POS_RIGHTOF; break;
|
|
case sisAbove: *pos = SDC_MMODE_POS_ABOVE; break;
|
|
case sisBelow: *pos = SDC_MMODE_POS_BELOW; break;
|
|
default: *pos = SDC_MMODE_POS_CLONE;
|
|
}
|
|
|
|
tmode = ((SiSMergedDisplayModePtr)mode->Private)->CRT1;
|
|
*crt1x = tmode->HDisplay;
|
|
*crt1y = tmode->VDisplay;
|
|
*crt1clk = (unsigned int)SiSCalcVRate(tmode);
|
|
|
|
tmode = ((SiSMergedDisplayModePtr)mode->Private)->CRT2;
|
|
*crt2x = tmode->HDisplay;
|
|
*crt2y = tmode->VDisplay;
|
|
*crt2clk = (unsigned int)SiSCalcVRate(tmode);
|
|
}
|
|
#endif
|
|
|
|
/***********************************
|
|
* MessageHandler interface *
|
|
* (unused now; use extension) *
|
|
***********************************/
|
|
|
|
#ifdef X_XF86MiscPassMessage
|
|
int
|
|
SISHandleMessage(int scrnIndex, const char *msgtype, const char *msgval, char **retmsg)
|
|
{
|
|
return BadMatch;
|
|
}
|
|
#endif
|
|
|
|
/***********************************
|
|
* SiSCtrl extension interface *
|
|
***********************************/
|
|
|
|
static void
|
|
sisutil_prepare_string(xSiSCtrlCommandReply *sdcbuf, char *mystring)
|
|
{
|
|
int slen = 0;
|
|
sdcbuf->sdc_buffer[0] = 0;
|
|
if(mystring) {
|
|
slen = strlen(mystring);
|
|
if(slen > 31) slen = 31;
|
|
strncpy(&sdcbuf->sdc_buffer[0], mystring, slen);
|
|
sdcbuf->sdc_buffer[slen] = 0;
|
|
}
|
|
sdcbuf->sdc_result[0] = slen;
|
|
}
|
|
|
|
static int
|
|
SiSHandleSiSDirectCommand(xSiSCtrlCommandReply *sdcbuf)
|
|
{
|
|
ScrnInfoPtr pScrn = xf86Screens[sdcbuf->screen];
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
#ifdef SISDUALHEAD
|
|
SISEntPtr pSiSEnt = pSiS->entityPrivate;
|
|
#endif
|
|
SISPortPrivPtr pPriv = NULL;
|
|
int i;
|
|
ULong j;
|
|
|
|
if(sdcbuf->sdc_id != SDC_ID) return BadMatch;
|
|
|
|
if(pSiS->adaptor) {
|
|
pPriv = GET_PORT_PRIVATE(pScrn);
|
|
}
|
|
|
|
j = sdcbuf->sdc_command;
|
|
for(i = 0; i < SDC_NUM_PARM_RESULT; i++) {
|
|
j += sdcbuf->sdc_parm[i];
|
|
}
|
|
|
|
if(j != sdcbuf->sdc_chksum) return BadMatch;
|
|
|
|
sdcbuf->sdc_result_header = SDC_RESULT_OK;
|
|
|
|
switch(sdcbuf->sdc_command) {
|
|
|
|
case SDC_CMD_GETVERSION:
|
|
sdcbuf->sdc_result[0] = SDC_VERSION;
|
|
sdcbuf->sdc_result[1] = SDC_MAXCOMMAND;
|
|
break;
|
|
|
|
case SDC_CMD_GETHWINFO:
|
|
{
|
|
UShort romptr = 0;
|
|
char *biosvers = NULL;
|
|
int slen = 0;
|
|
|
|
if(pSiS->BIOS) {
|
|
romptr = pSiS->BIOS[0x16] | (pSiS->BIOS[0x17] << 8);
|
|
if(romptr < 65530) {
|
|
biosvers = (char *)&pSiS->BIOS[romptr];
|
|
slen = strlen(biosvers);
|
|
if(slen > 10) slen = 10;
|
|
}
|
|
}
|
|
sdcbuf->sdc_result[0] = pSiS->IsAGPCard ? SDC_BUS_TYPE_AGP : SDC_BUS_TYPE_PCI;
|
|
if(pSiS->IsPCIExpress) sdcbuf->sdc_result[0] = SDC_BUS_TYPE_PCIE;
|
|
sdcbuf->sdc_result[1] = pSiS->PciBus;
|
|
sdcbuf->sdc_result[2] = pSiS->PciDevice;
|
|
sdcbuf->sdc_result[3] = pSiS->PciFunc;
|
|
sdcbuf->sdc_result[4] = pSiS->ROM661New ? 1 : (pSiS->HaveXGIBIOS ? 2 : 0),
|
|
sdcbuf->sdc_result[5] = pSiS->ChipFlags;
|
|
sdcbuf->sdc_result[6] = pSiS->ChipType;
|
|
sdcbuf->sdc_result[7] = pSiS->ChipRev;
|
|
sdcbuf->sdc_result[8] = SISDRIVERVERSIONYEAR;
|
|
sdcbuf->sdc_result[9] = SISDRIVERVERSIONMONTH;
|
|
sdcbuf->sdc_result[10] = SISDRIVERVERSIONDAY;
|
|
sdcbuf->sdc_result[11] = SISDRIVERREVISION;
|
|
sdcbuf->sdc_result[12] = pScrn->videoRam;
|
|
sdcbuf->sdc_result[13] = pSiS->UMAsize;
|
|
sdcbuf->sdc_result[14] = pSiS->LFBsize;
|
|
if(slen) strncpy(&sdcbuf->sdc_buffer[0], biosvers, slen);
|
|
sdcbuf->sdc_buffer[slen] = 0;
|
|
}
|
|
break;
|
|
|
|
case SDC_CMD_GETALLFLAGS:
|
|
sdcbuf->sdc_result[0] = SIS_VBFlagsVersion;
|
|
sdcbuf->sdc_result[1] = pSiS->VBFlags;
|
|
sdcbuf->sdc_result[2] = pSiS->SiS_SD_Flags;
|
|
sdcbuf->sdc_result[3] = pSiS->SiS_SD2_Flags;
|
|
sdcbuf->sdc_result[4] = pSiS->detectedCRT2Devices;
|
|
sdcbuf->sdc_result[5] = pSiS->VBFlags2;
|
|
sdcbuf->sdc_result[6] = pSiS->SiS_SD3_Flags;
|
|
sdcbuf->sdc_result[7] = pSiS->SiS_SD4_Flags;
|
|
sdcbuf->sdc_result[8] = pSiS->VBFlags3;
|
|
sdcbuf->sdc_result[9] = pSiS->VBFlags4;
|
|
break;
|
|
|
|
case SDC_CMD_GETVBFLAGSVERSION:
|
|
sdcbuf->sdc_result[0] = SIS_VBFlagsVersion;
|
|
break;
|
|
|
|
case SDC_CMD_GETVBFLAGS:
|
|
sdcbuf->sdc_result[0] = pSiS->VBFlags;
|
|
sdcbuf->sdc_result[1] = pSiS->VBFlags2;
|
|
sdcbuf->sdc_result[2] = pSiS->VBFlags3;
|
|
sdcbuf->sdc_result[3] = pSiS->VBFlags4;
|
|
break;
|
|
|
|
case SDC_CMD_CHECKMODEFORCRT2:
|
|
{
|
|
int clk, hd, hss, hse, ht, vd, vss, vse, vt, result;
|
|
ULong flags;
|
|
|
|
flags = sdcbuf->sdc_parm[0];
|
|
clk = sdcbuf->sdc_parm[1];
|
|
hd = sdcbuf->sdc_parm[2];
|
|
hss = sdcbuf->sdc_parm[3];
|
|
hse = sdcbuf->sdc_parm[4];
|
|
ht = sdcbuf->sdc_parm[5];
|
|
vd = sdcbuf->sdc_parm[6];
|
|
vss = sdcbuf->sdc_parm[7];
|
|
vse = sdcbuf->sdc_parm[8];
|
|
vt = sdcbuf->sdc_parm[9];
|
|
|
|
result = SISCheckModeTimingForCRT2Type(pScrn, (UShort)(flags & 0xff),
|
|
hd, vd, ht, vt, hss, hse, vss, vse, clk, pSiS->SCLogQuiet) & 0xff;
|
|
sdcbuf->sdc_result[0] = result;
|
|
}
|
|
break;
|
|
|
|
case SDC_CMD_SETVBFLAGS:
|
|
#ifdef SISDUALHEAD
|
|
if(!pSiS->DualHeadMode) {
|
|
#endif
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SISSwitchCRT2Type(pScrn, (ULong)sdcbuf->sdc_parm[0], pSiS->SCLogQuiet);
|
|
if(pPriv) SISUpdateVideoParms(pSiS, pPriv);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
#ifdef SISDUALHEAD
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
#endif
|
|
break;
|
|
|
|
case SDC_CMD_NEWSETVBFLAGS:
|
|
#ifdef SISDUALHEAD
|
|
if(!pSiS->DualHeadMode) {
|
|
#endif
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SISSwitchOutputType(pScrn, (ULong)sdcbuf->sdc_parm[0], (ULong)sdcbuf->sdc_parm[1],
|
|
(ULong)sdcbuf->sdc_parm[2], pSiS->SCLogQuiet);
|
|
if(pPriv) SISUpdateVideoParms(pSiS, pPriv);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
#ifdef SISDUALHEAD
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
#endif
|
|
break;
|
|
|
|
case SDC_CMD_GETDETECTEDDEVICES:
|
|
sdcbuf->sdc_result[0] = pSiS->detectedCRT2Devices;
|
|
break;
|
|
|
|
case SDC_CMD_REDETECTCRT2DEVICES:
|
|
#ifdef SISDUALHEAD
|
|
if(!pSiS->DualHeadMode) {
|
|
#endif
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SISRedetectCRT2Devices(pScrn);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
#ifdef SISDUALHEAD
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
#endif
|
|
break;
|
|
|
|
case SDC_CMD_GETCRT1STATUS:
|
|
sdcbuf->sdc_result[0] = pSiS->CRT1isoff ? 0 : 1;
|
|
break;
|
|
|
|
case SDC_CMD_SETCRT1STATUS:
|
|
#ifdef SISDUALHEAD
|
|
if(!pSiS->DualHeadMode) {
|
|
#endif
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SISSwitchCRT1Status(pScrn, (ULong)sdcbuf->sdc_parm[0], pSiS->SCLogQuiet);
|
|
if(pPriv) SISUpdateVideoParms(pSiS, pPriv);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
#ifdef SISDUALHEAD
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
#endif
|
|
break;
|
|
|
|
case SDC_CMD_GETSDFLAGS:
|
|
sdcbuf->sdc_result[0] = pSiS->SiS_SD_Flags;
|
|
break;
|
|
|
|
case SDC_CMD_GETSD2FLAGS:
|
|
sdcbuf->sdc_result[0] = pSiS->SiS_SD2_Flags;
|
|
break;
|
|
|
|
case SDC_CMD_GETLOCKSTATUS:
|
|
sdcbuf->sdc_result[0] = pSiS->xv_sisdirectunlocked;
|
|
break;
|
|
|
|
case SDC_CMD_SETLOCKSTATUS:
|
|
if(pSiS->enablesisctrl) {
|
|
if(sdcbuf->sdc_parm[0] == SIS_DIRECTKEY) {
|
|
pSiS->xv_sisdirectunlocked++;
|
|
} else if(pSiS->xv_sisdirectunlocked) {
|
|
pSiS->xv_sisdirectunlocked--;
|
|
}
|
|
} else {
|
|
pSiS->xv_sisdirectunlocked = 0;
|
|
sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
}
|
|
break;
|
|
|
|
case SDC_CMD_GETTVANTIFLICKER:
|
|
sdcbuf->sdc_result[0] = SiS_GetSISTVantiflicker(pScrn);
|
|
break;
|
|
|
|
case SDC_CMD_SETTVANTIFLICKER:
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetSISTVantiflicker(pScrn, (int)sdcbuf->sdc_parm[0]);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_GETTVSATURATION:
|
|
sdcbuf->sdc_result[0] = SiS_GetSISTVsaturation(pScrn);
|
|
break;
|
|
|
|
case SDC_CMD_SETTVSATURATION:
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetSISTVsaturation(pScrn, (int)sdcbuf->sdc_parm[0]);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_GETTVEDGEENHANCE:
|
|
sdcbuf->sdc_result[0] = SiS_GetSISTVedgeenhance(pScrn);;
|
|
break;
|
|
|
|
case SDC_CMD_SETTVEDGEENHANCE:
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetSISTVedgeenhance(pScrn, (int)sdcbuf->sdc_parm[0]);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_GETTVCFILTER:
|
|
sdcbuf->sdc_result[0] = SiS_GetSISTVcfilter(pScrn);
|
|
break;
|
|
|
|
case SDC_CMD_SETTVCFILTER:
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetSISTVcfilter(pScrn, sdcbuf->sdc_parm[0] ? 1 : 0);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_GETTVYFILTER:
|
|
sdcbuf->sdc_result[0] = SiS_GetSISTVyfilter(pScrn);
|
|
break;
|
|
|
|
case SDC_CMD_SETTVYFILTER:
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetSISTVyfilter(pScrn, sdcbuf->sdc_parm[0]);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_GETTVCOLORCALIB:
|
|
sdcbuf->sdc_result[0] = SiS_GetSISTVcolcalib(pScrn, TRUE) + 32768;
|
|
sdcbuf->sdc_result[1] = SiS_GetSISTVcolcalib(pScrn, FALSE) + 32768;
|
|
break;
|
|
|
|
case SDC_CMD_SETTVCOLORCALIB:
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetSISTVcolcalib(pScrn, (int)sdcbuf->sdc_parm[0] - 32768, TRUE);
|
|
SiS_SetSISTVcolcalib(pScrn, (int)sdcbuf->sdc_parm[1] - 32768, FALSE);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_GETTVCHCONTRAST:
|
|
sdcbuf->sdc_result[0] = SiS_GetCHTVcontrast(pScrn);
|
|
break;
|
|
|
|
case SDC_CMD_SETTVCHCONTRAST:
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetCHTVcontrast(pScrn, (int)sdcbuf->sdc_parm[0]);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_GETTVCHTEXTENHANCE:
|
|
sdcbuf->sdc_result[0] = SiS_GetCHTVtextenhance(pScrn);
|
|
break;
|
|
|
|
case SDC_CMD_SETTVCHTEXTENHANCE:
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetCHTVtextenhance(pScrn, (int)sdcbuf->sdc_parm[0]);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_GETTVCHCHROMAFLICKERFILTER:
|
|
sdcbuf->sdc_result[0] = SiS_GetCHTVchromaflickerfilter(pScrn);
|
|
break;
|
|
|
|
case SDC_CMD_SETTVCHCHROMAFLICKERFILTER:
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetCHTVchromaflickerfilter(pScrn, (int)sdcbuf->sdc_parm[0]);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_GETTVCHLUMAFLICKERFILTER:
|
|
sdcbuf->sdc_result[0] = SiS_GetCHTVlumaflickerfilter(pScrn);
|
|
break;
|
|
|
|
case SDC_CMD_SETTVCHLUMAFLICKERFILTER:
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetCHTVlumaflickerfilter(pScrn, (int)sdcbuf->sdc_parm[0]);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_GETTVCHCVBSCOLOR:
|
|
sdcbuf->sdc_result[0] = SiS_GetCHTVcvbscolor(pScrn);
|
|
break;
|
|
|
|
case SDC_CMD_SETTVCHCVBSCOLOR:
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetCHTVcvbscolor(pScrn, sdcbuf->sdc_parm[0] ? 1 : 0);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_GETCHTVOVERSCAN:
|
|
{ /* Changing of CRT2 settings not supported in DHM! */
|
|
int i = 0;
|
|
if(pSiS->OptTVSOver == 1) i = 3;
|
|
else if(pSiS->UseCHOverScan == 1) i = 2;
|
|
else if(pSiS->UseCHOverScan == 0) i = 1;
|
|
sdcbuf->sdc_result[0] = i;
|
|
}
|
|
break;
|
|
|
|
case SDC_CMD_SETCHTVOVERSCAN:
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
pSiS->UseCHOverScan = -1;
|
|
pSiS->OptTVSOver = FALSE;
|
|
if(sdcbuf->sdc_parm[0] == 3) {
|
|
if(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTSOVER) {
|
|
pSiS->OptTVSOver = TRUE;
|
|
}
|
|
pSiS->UseCHOverScan = 1;
|
|
} else if(sdcbuf->sdc_parm[0] == 2) pSiS->UseCHOverScan = 1;
|
|
else if(sdcbuf->sdc_parm[0] == 1) pSiS->UseCHOverScan = 0;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_GETGAMMASTATUS:
|
|
{
|
|
int i = 0;
|
|
#ifdef SISDUALHEAD
|
|
if(pSiS->DualHeadMode) {
|
|
if(pSiSEnt->CRT1gamma) i |= 0x01;
|
|
if(pSiSEnt->CRT2gamma) i |= 0x02;
|
|
} else {
|
|
#endif
|
|
if(pSiS->CRT1gamma) i |= 0x01;
|
|
if(pSiS->CRT2gamma) i |= 0x02;
|
|
if(pSiS->CRT2SepGamma) i |= 0x08;
|
|
#ifdef SISDUALHEAD
|
|
}
|
|
#endif
|
|
if(pSiS->XvGamma) i |= 0x04;
|
|
sdcbuf->sdc_result[0] = i;
|
|
}
|
|
break;
|
|
|
|
case SDC_CMD_SETGAMMASTATUS:
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
int value = sdcbuf->sdc_parm[0];
|
|
Bool backup = pSiS->XvGamma;
|
|
Bool backup2 = pSiS->CRT2SepGamma;
|
|
pSiS->CRT1gamma = (value & 0x01) ? TRUE : FALSE;
|
|
pSiS->CRT2gamma = (value & 0x02) ? TRUE : FALSE;
|
|
#ifdef SISDUALHEAD
|
|
if(pSiS->DualHeadMode) {
|
|
pSiSEnt->CRT1gamma = pSiS->CRT1gamma;
|
|
pSiSEnt->CRT2gamma = pSiS->CRT2gamma;
|
|
}
|
|
#endif
|
|
if(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTSGRCRT2) {
|
|
pSiS->CRT2SepGamma = (value & 0x08) ? TRUE : FALSE;
|
|
if(pSiS->CRT2SepGamma != backup2) {
|
|
if(pSiS->CRT2SepGamma) {
|
|
SiS_UpdateGammaCRT2(pScrn);
|
|
}
|
|
#ifdef SISGAMMARAMP
|
|
else {
|
|
SISCalculateGammaRamp(pScrn->pScreen, pScrn);
|
|
}
|
|
#endif
|
|
/* ATTN: When disabling CRT2 sep gamma,
|
|
* as long as SISGAMMARAMP is not defined,
|
|
* application needs to reset palette using
|
|
* vidmodextension! (See SiS_SD_CANSETGAMMA)
|
|
*
|
|
* Note: Difference between setting gamma values
|
|
* for CRT1 and CRT2: For CRT1, driver only
|
|
* stores the values, but does nothing with them;
|
|
* App needs to calc gamma ramp itself for CRT1,
|
|
* and set it using the VidModExtention.
|
|
* For CRT2, the driver will IMMEDIATELY recalc
|
|
* the palette.
|
|
*/
|
|
}
|
|
} else pSiS->CRT2SepGamma = FALSE;
|
|
|
|
pSiS->XvGamma = (value & 0x04) ? TRUE : FALSE;
|
|
if(pSiS->VGAEngine == SIS_315_VGA) {
|
|
if(backup != pSiS->XvGamma) {
|
|
if(pPriv) SiSUpdateXvGamma(pSiS, pPriv);
|
|
}
|
|
}
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_GETTVXSCALE:
|
|
sdcbuf->sdc_result[0] = SiS_GetTVxscale(pScrn) + 32768;
|
|
break;
|
|
|
|
case SDC_CMD_SETTVXSCALE:
|
|
{
|
|
int value = sdcbuf->sdc_parm[0] - 32768;
|
|
if((value < -16) || (value > 16)) {
|
|
sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
} else if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetTVxscale(pScrn, value);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
}
|
|
break;
|
|
|
|
case SDC_CMD_GETTVYSCALE:
|
|
sdcbuf->sdc_result[0] = SiS_GetTVyscale(pScrn) + 32768;
|
|
break;
|
|
|
|
case SDC_CMD_SETTVYSCALE:
|
|
{
|
|
int value = sdcbuf->sdc_parm[0] - 32768;
|
|
if((value < -4) || (value > 3)) {
|
|
sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
} else if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetTVyscale(pScrn, value);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
}
|
|
break;
|
|
|
|
case SDC_CMD_GETSCREENSIZE:
|
|
sdcbuf->sdc_result[0] = (pScrn->virtualX << 16) | pScrn->virtualY;
|
|
break;
|
|
|
|
case SDC_CMD_GETGAMMABRIGHTNESS: /* xv_BRx, xv_PBx */
|
|
sdcbuf->sdc_result[0] = pSiS->GammaBriR;
|
|
sdcbuf->sdc_result[1] = pSiS->GammaBriG;
|
|
sdcbuf->sdc_result[2] = pSiS->GammaBriB;
|
|
break;
|
|
|
|
case SDC_CMD_GETNEWGAMMABRICON: /* no xv pendant */
|
|
sdcbuf->sdc_result[0] = (CARD32)(((int)(pSiS->NewGammaBriR * 1000.0)) + 1000);
|
|
sdcbuf->sdc_result[1] = (CARD32)(((int)(pSiS->NewGammaBriG * 1000.0)) + 1000);
|
|
sdcbuf->sdc_result[2] = (CARD32)(((int)(pSiS->NewGammaBriB * 1000.0)) + 1000);
|
|
sdcbuf->sdc_result[3] = (CARD32)(((int)(pSiS->NewGammaConR * 1000.0)) + 1000);
|
|
sdcbuf->sdc_result[4] = (CARD32)(((int)(pSiS->NewGammaConG * 1000.0)) + 1000);
|
|
sdcbuf->sdc_result[5] = (CARD32)(((int)(pSiS->NewGammaConB * 1000.0)) + 1000);
|
|
break;
|
|
|
|
case SDC_CMD_SETGAMMABRIGHTNESS: /* xv_BRx, xv_PBx */
|
|
if(sdcbuf->sdc_parm[0] < 100 || sdcbuf->sdc_parm[0] > 10000 ||
|
|
sdcbuf->sdc_parm[1] < 100 || sdcbuf->sdc_parm[1] > 10000 ||
|
|
sdcbuf->sdc_parm[2] < 100 || sdcbuf->sdc_parm[2] > 10000) {
|
|
sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
} else if(pSiS->xv_sisdirectunlocked) {
|
|
pSiS->GammaBriR = sdcbuf->sdc_parm[0];
|
|
pSiS->GammaBriG = sdcbuf->sdc_parm[1];
|
|
pSiS->GammaBriB = sdcbuf->sdc_parm[2];
|
|
pSiS->NewGammaBriR = pSiS->NewGammaBriG = pSiS->NewGammaBriB = 0.0;
|
|
pSiS->NewGammaConR = pSiS->NewGammaConG = pSiS->NewGammaConB = 0.0;
|
|
pSiS->SiS_SD3_Flags |= SiS_SD3_OLDGAMMAINUSE;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_SETNEWGAMMABRICON: /* no xv pendant */
|
|
if(sdcbuf->sdc_parm[0] > 2000 || sdcbuf->sdc_parm[1] > 2000 ||
|
|
sdcbuf->sdc_parm[2] > 2000 || sdcbuf->sdc_parm[3] > 2000 ||
|
|
sdcbuf->sdc_parm[4] > 2000 || sdcbuf->sdc_parm[5] > 2000) {
|
|
sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
} else if(pSiS->xv_sisdirectunlocked) {
|
|
pSiS->NewGammaBriR = ((float)((int)sdcbuf->sdc_parm[0] - 1000)) / 1000.0;
|
|
pSiS->NewGammaBriG = ((float)((int)sdcbuf->sdc_parm[1] - 1000)) / 1000.0;
|
|
pSiS->NewGammaBriB = ((float)((int)sdcbuf->sdc_parm[2] - 1000)) / 1000.0;
|
|
pSiS->NewGammaConR = ((float)((int)sdcbuf->sdc_parm[3] - 1000)) / 1000.0;
|
|
pSiS->NewGammaConG = ((float)((int)sdcbuf->sdc_parm[4] - 1000)) / 1000.0;
|
|
pSiS->NewGammaConB = ((float)((int)sdcbuf->sdc_parm[5] - 1000)) / 1000.0;
|
|
pSiS->GammaBriR = pSiS->GammaBriG = pSiS->GammaBriB = 1000;
|
|
pSiS->SiS_SD3_Flags &= ~SiS_SD3_OLDGAMMAINUSE;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_GETGAMMABRIGHTNESS2: /* xv_BRx2, xv_PBx2 */
|
|
#ifdef SISDUALHEAD
|
|
if(pSiS->DualHeadMode) {
|
|
sdcbuf->sdc_result[0] = pSiSEnt->GammaBriR;
|
|
sdcbuf->sdc_result[1] = pSiSEnt->GammaBriG;
|
|
sdcbuf->sdc_result[2] = pSiSEnt->GammaBriB;
|
|
break;
|
|
}
|
|
#endif
|
|
sdcbuf->sdc_result[0] = pSiS->GammaBriR;
|
|
sdcbuf->sdc_result[1] = pSiS->GammaBriG;
|
|
sdcbuf->sdc_result[2] = pSiS->GammaBriB;
|
|
break;
|
|
|
|
case SDC_CMD_GETNEWGAMMABRICON2: /* no xv pendant */
|
|
#ifdef SISDUALHEAD
|
|
if(pSiS->DualHeadMode) {
|
|
sdcbuf->sdc_result[0] = (CARD32)(((int)(pSiSEnt->NewGammaBriR * 1000.0)) + 1000);
|
|
sdcbuf->sdc_result[1] = (CARD32)(((int)(pSiSEnt->NewGammaBriG * 1000.0)) + 1000);
|
|
sdcbuf->sdc_result[2] = (CARD32)(((int)(pSiSEnt->NewGammaBriB * 1000.0)) + 1000);
|
|
sdcbuf->sdc_result[3] = (CARD32)(((int)(pSiSEnt->NewGammaConR * 1000.0)) + 1000);
|
|
sdcbuf->sdc_result[4] = (CARD32)(((int)(pSiSEnt->NewGammaConG * 1000.0)) + 1000);
|
|
sdcbuf->sdc_result[5] = (CARD32)(((int)(pSiSEnt->NewGammaConB * 1000.0)) + 1000);
|
|
break;
|
|
}
|
|
#endif
|
|
sdcbuf->sdc_result[0] = (CARD32)(((int)(pSiS->NewGammaBriR * 1000.0)) + 1000);
|
|
sdcbuf->sdc_result[1] = (CARD32)(((int)(pSiS->NewGammaBriG * 1000.0)) + 1000);
|
|
sdcbuf->sdc_result[2] = (CARD32)(((int)(pSiS->NewGammaBriB * 1000.0)) + 1000);
|
|
sdcbuf->sdc_result[3] = (CARD32)(((int)(pSiS->NewGammaConR * 1000.0)) + 1000);
|
|
sdcbuf->sdc_result[4] = (CARD32)(((int)(pSiS->NewGammaConG * 1000.0)) + 1000);
|
|
sdcbuf->sdc_result[5] = (CARD32)(((int)(pSiS->NewGammaConB * 1000.0)) + 1000);
|
|
break;
|
|
|
|
case SDC_CMD_SETGAMMABRIGHTNESS2: /* xv_BRx2, xv_PBx2 */
|
|
if(sdcbuf->sdc_parm[0] < 100 || sdcbuf->sdc_parm[0] > 10000 ||
|
|
sdcbuf->sdc_parm[1] < 100 || sdcbuf->sdc_parm[1] > 10000 ||
|
|
sdcbuf->sdc_parm[2] < 100 || sdcbuf->sdc_parm[2] > 10000) {
|
|
sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
} else if(pSiS->xv_sisdirectunlocked) {
|
|
pSiS->SiS_SD3_Flags |= SiS_SD3_OLDGAMMAINUSE;
|
|
#ifdef SISDUALHEAD
|
|
if(pSiS->DualHeadMode) {
|
|
pSiSEnt->GammaBriR = sdcbuf->sdc_parm[0];
|
|
pSiSEnt->GammaBriG = sdcbuf->sdc_parm[1];
|
|
pSiSEnt->GammaBriB = sdcbuf->sdc_parm[2];
|
|
pSiSEnt->NewGammaBriR = pSiSEnt->NewGammaBriG = pSiSEnt->NewGammaBriB = 0.0;
|
|
pSiSEnt->NewGammaConR = pSiSEnt->NewGammaConG = pSiSEnt->NewGammaConB = 0.0;
|
|
}
|
|
#endif
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_SETNEWGAMMABRICON2: /* no xv pendant */
|
|
if(sdcbuf->sdc_parm[0] > 2000 || sdcbuf->sdc_parm[1] > 2000 ||
|
|
sdcbuf->sdc_parm[2] > 2000 || sdcbuf->sdc_parm[3] > 2000 ||
|
|
sdcbuf->sdc_parm[4] > 2000 || sdcbuf->sdc_parm[5] > 2000) {
|
|
sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
} else if(pSiS->xv_sisdirectunlocked) {
|
|
pSiS->SiS_SD3_Flags &= ~SiS_SD3_OLDGAMMAINUSE;
|
|
#ifdef SISDUALHEAD
|
|
if(pSiS->DualHeadMode) {
|
|
pSiSEnt->NewGammaBriR = ((float)((int)sdcbuf->sdc_parm[0] - 1000)) / 1000.0;
|
|
pSiSEnt->NewGammaBriG = ((float)((int)sdcbuf->sdc_parm[1] - 1000)) / 1000.0;
|
|
pSiSEnt->NewGammaBriB = ((float)((int)sdcbuf->sdc_parm[2] - 1000)) / 1000.0;
|
|
pSiSEnt->NewGammaConR = ((float)((int)sdcbuf->sdc_parm[3] - 1000)) / 1000.0;
|
|
pSiSEnt->NewGammaConG = ((float)((int)sdcbuf->sdc_parm[4] - 1000)) / 1000.0;
|
|
pSiSEnt->NewGammaConB = ((float)((int)sdcbuf->sdc_parm[5] - 1000)) / 1000.0;
|
|
pSiSEnt->GammaBriR = pSiSEnt->GammaBriG = pSiSEnt->GammaBriB = 1000;
|
|
}
|
|
#endif
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_GETGETGAMMACRT2:
|
|
sdcbuf->sdc_result[0] = (ULong)(pSiS->GammaR2 * 1000);
|
|
sdcbuf->sdc_result[1] = (ULong)(pSiS->GammaG2 * 1000);
|
|
sdcbuf->sdc_result[2] = (ULong)(pSiS->GammaB2 * 1000);
|
|
sdcbuf->sdc_result[3] = pSiS->GammaBriR2;
|
|
sdcbuf->sdc_result[4] = pSiS->GammaBriG2;
|
|
sdcbuf->sdc_result[5] = pSiS->GammaBriB2;
|
|
break;
|
|
|
|
case SDC_CMD_GETGETNEWGAMMACRT2:
|
|
sdcbuf->sdc_result[0] = (ULong)(pSiS->GammaR2 * 1000);
|
|
sdcbuf->sdc_result[1] = (ULong)(pSiS->GammaG2 * 1000);
|
|
sdcbuf->sdc_result[2] = (ULong)(pSiS->GammaB2 * 1000);
|
|
sdcbuf->sdc_result[3] = (CARD32)(((int)(pSiS->NewGammaBriR2 * 1000.0)) + 1000);
|
|
sdcbuf->sdc_result[4] = (CARD32)(((int)(pSiS->NewGammaBriG2 * 1000.0)) + 1000);
|
|
sdcbuf->sdc_result[5] = (CARD32)(((int)(pSiS->NewGammaBriB2 * 1000.0)) + 1000);
|
|
sdcbuf->sdc_result[6] = (CARD32)(((int)(pSiS->NewGammaConR2 * 1000.0)) + 1000);
|
|
sdcbuf->sdc_result[7] = (CARD32)(((int)(pSiS->NewGammaConG2 * 1000.0)) + 1000);
|
|
sdcbuf->sdc_result[8] = (CARD32)(((int)(pSiS->NewGammaConB2 * 1000.0)) + 1000);
|
|
break;
|
|
|
|
case SDC_CMD_SETGETGAMMACRT2:
|
|
if(sdcbuf->sdc_parm[0] < 100 || sdcbuf->sdc_parm[0] > 10000 ||
|
|
sdcbuf->sdc_parm[1] < 100 || sdcbuf->sdc_parm[1] > 10000 ||
|
|
sdcbuf->sdc_parm[2] < 100 || sdcbuf->sdc_parm[2] > 10000 ||
|
|
sdcbuf->sdc_parm[3] < 100 || sdcbuf->sdc_parm[3] > 10000 ||
|
|
sdcbuf->sdc_parm[4] < 100 || sdcbuf->sdc_parm[4] > 10000 ||
|
|
sdcbuf->sdc_parm[5] < 100 || sdcbuf->sdc_parm[5] > 10000) {
|
|
sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
} else if(pSiS->xv_sisdirectunlocked) {
|
|
pSiS->GammaR2 = (float)sdcbuf->sdc_parm[0] / (float)1000;
|
|
pSiS->GammaG2 = (float)sdcbuf->sdc_parm[1] / (float)1000;
|
|
pSiS->GammaB2 = (float)sdcbuf->sdc_parm[2] / (float)1000;
|
|
pSiS->GammaBriR2 = sdcbuf->sdc_parm[3];
|
|
pSiS->GammaBriG2 = sdcbuf->sdc_parm[4];
|
|
pSiS->GammaBriB2 = sdcbuf->sdc_parm[5];
|
|
pSiS->NewGammaBriR2 = pSiS->NewGammaBriG2 = pSiS->NewGammaBriB2 = 0.0;
|
|
pSiS->NewGammaConR2 = pSiS->NewGammaConG2 = pSiS->NewGammaConB2 = 0.0;
|
|
pSiS->SiS_SD3_Flags |= SiS_SD3_OLDGAMMAINUSE;
|
|
SiS_UpdateGammaCRT2(pScrn);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_SETGETNEWGAMMACRT2:
|
|
if(sdcbuf->sdc_parm[0] < 100 || sdcbuf->sdc_parm[0] > 10000 ||
|
|
sdcbuf->sdc_parm[1] < 100 || sdcbuf->sdc_parm[1] > 10000 ||
|
|
sdcbuf->sdc_parm[2] < 100 || sdcbuf->sdc_parm[2] > 10000 ||
|
|
sdcbuf->sdc_parm[3] > 2000 || sdcbuf->sdc_parm[4] > 2000 ||
|
|
sdcbuf->sdc_parm[5] > 2000 || sdcbuf->sdc_parm[6] > 2000 ||
|
|
sdcbuf->sdc_parm[7] > 2000 || sdcbuf->sdc_parm[8] > 2000) {
|
|
sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
} else if(pSiS->xv_sisdirectunlocked) {
|
|
pSiS->GammaR2 = (float)sdcbuf->sdc_parm[0] / (float)1000;
|
|
pSiS->GammaG2 = (float)sdcbuf->sdc_parm[1] / (float)1000;
|
|
pSiS->GammaB2 = (float)sdcbuf->sdc_parm[2] / (float)1000;
|
|
pSiS->NewGammaBriR2 = ((float)((int)sdcbuf->sdc_parm[3] - 1000)) / 1000.0;
|
|
pSiS->NewGammaBriG2 = ((float)((int)sdcbuf->sdc_parm[4] - 1000)) / 1000.0;
|
|
pSiS->NewGammaBriB2 = ((float)((int)sdcbuf->sdc_parm[5] - 1000)) / 1000.0;
|
|
pSiS->NewGammaConR2 = ((float)((int)sdcbuf->sdc_parm[6] - 1000)) / 1000.0;
|
|
pSiS->NewGammaConG2 = ((float)((int)sdcbuf->sdc_parm[7] - 1000)) / 1000.0;
|
|
pSiS->NewGammaConB2 = ((float)((int)sdcbuf->sdc_parm[8] - 1000)) / 1000.0;
|
|
pSiS->GammaBriR2 = pSiS->GammaBriG2 = pSiS->GammaBriB2 = 1000;
|
|
pSiS->SiS_SD3_Flags &= ~SiS_SD3_OLDGAMMAINUSE;
|
|
SiS_UpdateGammaCRT2(pScrn);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_GETHWCURSORSTATUS:
|
|
sdcbuf->sdc_result[0] = pSiS->HideHWCursor ? 1 : 0;
|
|
break;
|
|
|
|
case SDC_CMD_SETHWCURSORSTATUS:
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
Bool VisibleBackup = pSiS->HWCursorIsVisible;
|
|
pSiS->HideHWCursor = sdcbuf->sdc_parm[0] ? TRUE : FALSE;
|
|
if(pSiS->CursorInfoPtr) {
|
|
if(VisibleBackup) {
|
|
if(sdcbuf->sdc_parm[0]) {
|
|
(pSiS->CursorInfoPtr->HideCursor)(pScrn);
|
|
} else {
|
|
(pSiS->CursorInfoPtr->ShowCursor)(pScrn);
|
|
}
|
|
}
|
|
pSiS->HWCursorIsVisible = VisibleBackup;
|
|
}
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_GETPANELMODE:
|
|
{
|
|
int i = 0;
|
|
if(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTSCALE) {
|
|
switch(pSiS->SiS_Pr->UsePanelScaler) {
|
|
case -1: i |= 0x01; break;
|
|
case 1: i |= 0x02; break;
|
|
}
|
|
if(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTCENTER) {
|
|
switch(pSiS->SiS_Pr->CenterScreen) {
|
|
case -1: i |= 0x04; break;
|
|
case 1: i |= 0x08; break;
|
|
}
|
|
}
|
|
}
|
|
sdcbuf->sdc_result[0] = i;
|
|
}
|
|
break;
|
|
|
|
case SDC_CMD_SETPANELMODE:
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
int value = sdcbuf->sdc_parm[0];
|
|
if(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTSCALE) {
|
|
if(value & 0x01) pSiS->SiS_Pr->UsePanelScaler = -1;
|
|
else if(value & 0x02) pSiS->SiS_Pr->UsePanelScaler = 1;
|
|
else pSiS->SiS_Pr->UsePanelScaler = 0;
|
|
if(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTCENTER) {
|
|
if(value & 0x04) pSiS->SiS_Pr->CenterScreen = -1;
|
|
else if(value & 0x08) pSiS->SiS_Pr->CenterScreen = 1;
|
|
else pSiS->SiS_Pr->CenterScreen = 0;
|
|
}
|
|
}
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
case SDC_CMD_GETMERGEDMODEDETAILS:
|
|
#ifdef SISMERGED
|
|
if(pSiS->MergedFB) {
|
|
int clk, hd, hss, hse, ht, vd, vss, vse, vt;
|
|
unsigned int pos, crt1x, crt1y, crt1clk, crt2x, crt2y, crt2clk;
|
|
|
|
clk = sdcbuf->sdc_parm[0];
|
|
hd = sdcbuf->sdc_parm[1];
|
|
hss = sdcbuf->sdc_parm[2];
|
|
hse = sdcbuf->sdc_parm[3];
|
|
ht = sdcbuf->sdc_parm[4];
|
|
vd = sdcbuf->sdc_parm[5];
|
|
vss = sdcbuf->sdc_parm[6];
|
|
vse = sdcbuf->sdc_parm[7];
|
|
vt = sdcbuf->sdc_parm[8];
|
|
|
|
SISGetMergedModeDetails(pScrn,
|
|
hd, vd, ht, vt, hss, hse, vss, vse, clk,
|
|
&pos, &crt1x, &crt1y, &crt1clk, &crt2x, &crt2y, &crt2clk);
|
|
|
|
sdcbuf->sdc_result[0] = pos;
|
|
sdcbuf->sdc_result[1] = crt1x;
|
|
sdcbuf->sdc_result[2] = crt1y;
|
|
sdcbuf->sdc_result[3] = crt1clk;
|
|
sdcbuf->sdc_result[4] = crt2x;
|
|
sdcbuf->sdc_result[5] = crt2y;
|
|
sdcbuf->sdc_result[6] = crt2clk;
|
|
|
|
switch(pSiS->CRT2Position) {
|
|
case sisLeftOf: sdcbuf->sdc_result[7] = SDC_MMODE_POS_LEFTOF; break;
|
|
case sisRightOf: sdcbuf->sdc_result[7] = SDC_MMODE_POS_RIGHTOF; break;
|
|
case sisAbove: sdcbuf->sdc_result[7] = SDC_MMODE_POS_ABOVE; break;
|
|
case sisBelow: sdcbuf->sdc_result[7] = SDC_MMODE_POS_BELOW; break;
|
|
default: sdcbuf->sdc_result[7] = SDC_MMODE_POS_CLONE;
|
|
}
|
|
|
|
} else
|
|
#endif
|
|
sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_GETDEVICENAME: /* In DualHead mode, this returns CRT1 data */
|
|
{
|
|
SISPtr mypSiS = pSiS;
|
|
sdcbuf->sdc_result[0] = 0;
|
|
#ifdef SISDUALHEAD
|
|
if(pSiS->DualHeadMode) {
|
|
if(pSiSEnt->pScrn_2) mypSiS = SISPTR(pSiSEnt->pScrn_2);
|
|
}
|
|
#endif
|
|
sisutil_prepare_string(sdcbuf, mypSiS->devsectname);
|
|
}
|
|
break;
|
|
|
|
case SDC_CMD_GETMONITORNAME: /* In DualHead mode, this returns CRT1 data */
|
|
{
|
|
ScrnInfoPtr mypScrn = pScrn;
|
|
sdcbuf->sdc_result[0] = 0;
|
|
#ifdef SISDUALHEAD
|
|
if(pSiS->DualHeadMode) {
|
|
if(pSiSEnt->pScrn_2) mypScrn = pSiSEnt->pScrn_2;
|
|
}
|
|
#endif
|
|
if(mypScrn->monitor) {
|
|
sisutil_prepare_string(sdcbuf, mypScrn->monitor->id);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SDC_CMD_GETDEVICENAME2: /* In DualHead mode, this returns CRT2 data */
|
|
sdcbuf->sdc_result[0] = 0;
|
|
#ifdef SISDUALHEAD
|
|
if(pSiS->DualHeadMode) {
|
|
if(pSiSEnt->pScrn_1) {
|
|
sisutil_prepare_string(sdcbuf, SISPTR(pSiSEnt->pScrn_1)->devsectname);
|
|
}
|
|
} else
|
|
#endif
|
|
sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_GETMONITORNAME2: /* In DualHead mode, this returns CRT2 data */
|
|
sdcbuf->sdc_result[0] = 0;
|
|
#ifdef SISDUALHEAD
|
|
if(pSiS->DualHeadMode) {
|
|
if(pSiSEnt->pScrn_1) {
|
|
if(pSiSEnt->pScrn_1->monitor) {
|
|
sisutil_prepare_string(sdcbuf, pSiSEnt->pScrn_1->monitor->id);
|
|
}
|
|
}
|
|
} else
|
|
#endif
|
|
sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_SETXVBRIGHTNESS:
|
|
if(pPriv) {
|
|
int val = sdcbuf->sdc_parm[0] - 32768;
|
|
if(val >= -128 && val <= 127) pPriv->brightness = val;
|
|
else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_GETXVBRIGHTNESS:
|
|
if(pPriv) {
|
|
sdcbuf->sdc_result[0] = pPriv->brightness + 32768;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_SETXVCONTRAST:
|
|
if(pPriv) {
|
|
int val = sdcbuf->sdc_parm[0] - 32768;
|
|
if(val >= 0 && val <= 7) pPriv->contrast = val;
|
|
else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_GETXVCONTRAST:
|
|
if(pPriv) {
|
|
sdcbuf->sdc_result[0] = pPriv->contrast + 32768;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_SETXVHUE:
|
|
if((pPriv) && (pSiS->SiS_SD2_Flags & SiS_SD2_SUPPORTXVHUESAT)) {
|
|
int val = sdcbuf->sdc_parm[0] - 32768;
|
|
if(val >= -8 && val <= 7) pPriv->hue = val;
|
|
else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_GETXVHUE:
|
|
if((pPriv) && (pSiS->SiS_SD2_Flags & SiS_SD2_SUPPORTXVHUESAT)) {
|
|
sdcbuf->sdc_result[0] = pPriv->hue + 32768;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_SETXVSATURATION:
|
|
if((pPriv) && (pSiS->SiS_SD2_Flags & SiS_SD2_SUPPORTXVHUESAT)) {
|
|
int val = sdcbuf->sdc_parm[0] - 32768;
|
|
if(val >= -7 && val <= 7) pPriv->saturation = val;
|
|
else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_GETXVSATURATION:
|
|
if((pPriv) && (pSiS->SiS_SD2_Flags & SiS_SD2_SUPPORTXVHUESAT)) {
|
|
sdcbuf->sdc_result[0] = pPriv->saturation + 32768;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_SETXVGAMMA:
|
|
if((pPriv) && (pSiS->SiS_SD_Flags & SiS_SD_SUPPORTXVGAMMA1)) {
|
|
if(sdcbuf->sdc_parm[0] < 100 || sdcbuf->sdc_parm[0] > 10000 ||
|
|
sdcbuf->sdc_parm[1] < 100 || sdcbuf->sdc_parm[1] > 10000 ||
|
|
sdcbuf->sdc_parm[2] < 100 || sdcbuf->sdc_parm[2] > 10000) {
|
|
sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
} else {
|
|
pSiS->XvGammaRed = sdcbuf->sdc_parm[0];
|
|
pSiS->XvGammaGreen = sdcbuf->sdc_parm[1];
|
|
pSiS->XvGammaBlue = sdcbuf->sdc_parm[2];
|
|
SiSUpdateXvGamma(pSiS, pPriv);
|
|
}
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_GETXVGAMMA:
|
|
if((pPriv) && (pSiS->SiS_SD_Flags & SiS_SD_SUPPORTXVGAMMA1)) {
|
|
sdcbuf->sdc_result[0] = pSiS->XvGammaRed;
|
|
sdcbuf->sdc_result[1] = pSiS->XvGammaGreen;
|
|
sdcbuf->sdc_result[2] = pSiS->XvGammaBlue;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_SETXVCOLORKEY:
|
|
if(pPriv) {
|
|
pPriv->colorKey = pSiS->colorKey = sdcbuf->sdc_parm[0];
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_GETXVCOLORKEY:
|
|
if(pPriv) {
|
|
sdcbuf->sdc_result[0] = pPriv->colorKey;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_SETXVAUTOPAINTCOLORKEY:
|
|
if(pPriv) {
|
|
pPriv->autopaintColorKey = sdcbuf->sdc_parm[0] ? 1 : 0;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_GETXVAUTOPAINTCOLORKEY:
|
|
if(pPriv) {
|
|
sdcbuf->sdc_result[0] = pPriv->autopaintColorKey ? 1 : 0;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_SETXVDEFAULTS:
|
|
if(pPriv) {
|
|
SISSetPortDefaults(pScrn, pPriv);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_SETXVDISABLEGFX:
|
|
if(pPriv) {
|
|
pPriv->disablegfx = sdcbuf->sdc_parm[0] ? 1 : 0;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_GETXVDISABLEGFX:
|
|
if(pPriv) {
|
|
sdcbuf->sdc_result[0] = pPriv->disablegfx ? 1 : 0;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_SETXVDISABLEGFXLR:
|
|
if(pPriv) {
|
|
pPriv->disablegfxlr = sdcbuf->sdc_parm[0] ? 1 : 0;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_GETXVDISABLEGFXLR:
|
|
if(pPriv) {
|
|
sdcbuf->sdc_result[0] = pPriv->disablegfxlr ? 1 : 0;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_SETXVSWITCHCRT:
|
|
if((pPriv) && (pSiS->VGAEngine == SIS_315_VGA)) {
|
|
if(pPriv->AllowSwitchCRT) {
|
|
pPriv->crtnum = sdcbuf->sdc_parm[0] ? 1 : 0;
|
|
#ifdef SISDUALHEAD
|
|
if(pPriv->dualHeadMode) pSiSEnt->curxvcrtnum = pPriv->crtnum;
|
|
#endif
|
|
}
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_GETXVSWITCHCRT:
|
|
if((pPriv) && (pSiS->VGAEngine == SIS_315_VGA)) {
|
|
#ifdef SISDUALHEAD
|
|
if(pPriv->dualHeadMode)
|
|
sdcbuf->sdc_result[0] = pSiSEnt->curxvcrtnum;
|
|
else
|
|
#endif
|
|
sdcbuf->sdc_result[0] = pPriv->crtnum;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
|
|
case SDC_CMD_SETTVXPOS:
|
|
{
|
|
int value = sdcbuf->sdc_parm[0] - 32768;
|
|
if((value < -32) || (value > 32)) {
|
|
sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
} else if(pSiS->xv_sisdirectunlocked) {
|
|
pPriv->tvxpos = value;
|
|
SiS_SetTVxposoffset(pScrn, pPriv->tvxpos);
|
|
pPriv->updatetvxpos = FALSE;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
}
|
|
break;
|
|
|
|
case SDC_CMD_GETTVXPOS:
|
|
sdcbuf->sdc_result[0] = SiS_GetTVxposoffset(pScrn) + 32768;
|
|
break;
|
|
|
|
case SDC_CMD_SETTVYPOS:
|
|
{
|
|
int value = sdcbuf->sdc_parm[0] - 32768;
|
|
if((value < -32) || (value > 32)) {
|
|
sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
} else if(pSiS->xv_sisdirectunlocked) {
|
|
pPriv->tvypos = value;
|
|
SiS_SetTVyposoffset(pScrn, pPriv->tvypos);
|
|
pPriv->updatetvypos = FALSE;
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
}
|
|
break;
|
|
|
|
case SDC_CMD_GETTVYPOS:
|
|
sdcbuf->sdc_result[0] = SiS_GetTVyposoffset(pScrn) + 32768;
|
|
break;
|
|
|
|
case SDC_CMD_SETXVDEINT:
|
|
case SDC_CMD_GETXVDEINT:
|
|
sdcbuf->sdc_result_header = SDC_RESULT_INVAL;
|
|
break;
|
|
|
|
case SDC_CMD_GETMONGAMMACRT1:
|
|
sdcbuf->sdc_result[0] = pSiS->CRT1MonGamma;
|
|
break;
|
|
|
|
case SDC_CMD_GETMONGAMMACRT2:
|
|
sdcbuf->sdc_result[0] = pSiS->CRT2MonGamma;
|
|
break;
|
|
|
|
case SDC_CMD_LOGQUIET:
|
|
pSiS->SCLogQuiet = sdcbuf->sdc_parm[0] ? TRUE : FALSE;
|
|
break;
|
|
|
|
case SDC_CMD_GETCRT1SATGAIN:
|
|
sdcbuf->sdc_result[0] = SiS_GetSISCRT1SaturationGain(pScrn);
|
|
break;
|
|
|
|
case SDC_CMD_SETCRT1SATGAIN:
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetSISCRT1SaturationGain(pScrn, (int)sdcbuf->sdc_parm[0]);
|
|
} else sdcbuf->sdc_result_header = SDC_RESULT_NOPERM;
|
|
break;
|
|
|
|
default:
|
|
sdcbuf->sdc_result_header = SDC_RESULT_UNDEFCMD;
|
|
}
|
|
|
|
return Success;
|
|
}
|
|
|
|
/* Proc */
|
|
|
|
static int
|
|
SiSProcSiSCtrlQueryVersion(ClientPtr client)
|
|
{
|
|
xSiSCtrlQueryVersionReply rep;
|
|
register int n;
|
|
|
|
REQUEST_SIZE_MATCH(xSiSCtrlQueryVersionReq);
|
|
rep.type = X_Reply;
|
|
rep.length = 0;
|
|
rep.sequenceNumber = client->sequence;
|
|
rep.majorVersion = SISCTRL_MAJOR_VERSION;
|
|
rep.minorVersion = SISCTRL_MINOR_VERSION;
|
|
if(client->swapped) {
|
|
swaps(&rep.sequenceNumber, n);
|
|
swapl(&rep.length, n);
|
|
swaps(&rep.majorVersion, n);
|
|
swaps(&rep.minorVersion, n);
|
|
}
|
|
WriteToClient(client, sizeof(xSiSCtrlQueryVersionReply), (char *)&rep);
|
|
return (client->noClientException);
|
|
}
|
|
|
|
static int
|
|
SiSProcSiSCtrlCommand(ClientPtr client)
|
|
{
|
|
REQUEST(xSiSCtrlCommandReq);
|
|
xSiSCtrlCommandReply rep;
|
|
ExtensionEntry *myext;
|
|
xSiSCtrlScreenTable *myctrl;
|
|
register int n;
|
|
int i, ret;
|
|
|
|
REQUEST_SIZE_MATCH(xSiSCtrlCommandReq);
|
|
|
|
memcpy(&rep, stuff, sizeof(xSiSCtrlCommandReply));
|
|
|
|
/* Get pointer to ExtensionEntry */
|
|
if(!(myext = CheckExtension(SISCTRL_PROTOCOL_NAME))) return BadMatch;
|
|
|
|
/* Get pointer to our private */
|
|
if(!(myctrl = (xSiSCtrlScreenTable *)myext->extPrivate)) return BadMatch;
|
|
|
|
/* Check if screen index is within out limits */
|
|
if(rep.screen > myctrl->maxscreens) return BadMatch;
|
|
|
|
/* Check if this screen has added itself */
|
|
if(!(myctrl->HandleSiSDirectCommand[rep.screen])) return BadMatch;
|
|
|
|
/* Finally, execute the command */
|
|
if((ret = (myctrl->HandleSiSDirectCommand[rep.screen])(&rep)) != Success)
|
|
return ret;
|
|
|
|
rep.type = X_Reply;
|
|
rep.length = (sizeof(xSiSCtrlCommandReply) - sizeof(xGenericReply)) >> 2;
|
|
rep.sequenceNumber = client->sequence;
|
|
|
|
if(client->swapped) {
|
|
swaps(&rep.sequenceNumber, n);
|
|
swapl(&rep.length, n);
|
|
swapl(&rep.screen, n);
|
|
swapl(&rep.sdc_id, n);
|
|
swapl(&rep.sdc_command, n);
|
|
swapl(&rep.sdc_result_header, n);
|
|
for(i = 0; i < SDC_NUM_PARM_RESULT; i++) {
|
|
swapl(&rep.sdc_parm[i], n);
|
|
swapl(&rep.sdc_result[i], n);
|
|
}
|
|
}
|
|
WriteToClient(client, sizeof(xSiSCtrlCommandReply), (char *)&rep);
|
|
return client->noClientException;
|
|
}
|
|
|
|
static int
|
|
SiSProcSiSCtrlDispatch(ClientPtr client)
|
|
{
|
|
REQUEST(xReq);
|
|
switch(stuff->data) {
|
|
case X_SiSCtrlQueryVersion:
|
|
return SiSProcSiSCtrlQueryVersion(client);
|
|
case X_SiSCtrlCommand:
|
|
return SiSProcSiSCtrlCommand(client);
|
|
}
|
|
return BadRequest;
|
|
}
|
|
|
|
/* SProc */
|
|
|
|
static int
|
|
SiSSProcSiSCtrlQueryVersion(ClientPtr client)
|
|
{
|
|
REQUEST(xSiSCtrlQueryVersionReq);
|
|
register int n;
|
|
swaps(&stuff->length, n);
|
|
REQUEST_SIZE_MATCH(xSiSCtrlQueryVersionReq);
|
|
return SiSProcSiSCtrlQueryVersion(client);
|
|
}
|
|
|
|
static int
|
|
SiSSProcSiSCtrlCommand(ClientPtr client)
|
|
{
|
|
REQUEST(xSiSCtrlCommandReq);
|
|
register int n;
|
|
int i;
|
|
swaps(&stuff->length, n);
|
|
swapl(&stuff->screen, n);
|
|
swapl(&stuff->sdc_id, n);
|
|
swapl(&stuff->sdc_command, n);
|
|
swapl(&stuff->sdc_result_header, n);
|
|
for(i = 0; i < SDC_NUM_PARM_RESULT; i++) {
|
|
swapl(&stuff->sdc_parm[i], n);
|
|
swapl(&stuff->sdc_result[i], n);
|
|
}
|
|
REQUEST_SIZE_MATCH(xSiSCtrlCommandReq);
|
|
return SiSProcSiSCtrlCommand(client);
|
|
}
|
|
|
|
static int
|
|
SiSSProcSiSCtrlDispatch(ClientPtr client)
|
|
{
|
|
REQUEST(xReq);
|
|
switch(stuff->data) {
|
|
case X_SiSCtrlQueryVersion:
|
|
return SiSSProcSiSCtrlQueryVersion(client);
|
|
case X_SiSCtrlCommand:
|
|
return SiSSProcSiSCtrlCommand(client);
|
|
}
|
|
return BadRequest;
|
|
}
|
|
|
|
static void
|
|
SiSCtrlResetProc(ExtensionEntry* extEntry)
|
|
{
|
|
/* Called by CloseDownExtensions() */
|
|
/* (CloseDownExtensions() is called BEFORE CloseScreen,
|
|
* which is why we must not use pSiS->SiSCtrlExtEntry
|
|
* in SiSCtrlExtUnregister())
|
|
*/
|
|
if(extEntry->extPrivate) {
|
|
xfree(extEntry->extPrivate);
|
|
extEntry->extPrivate = NULL;
|
|
}
|
|
}
|
|
|
|
void
|
|
SiSCtrlExtInit(ScrnInfoPtr pScrn)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
ExtensionEntry *myext;
|
|
xSiSCtrlScreenTable *myctrl;
|
|
unsigned int version, revision;
|
|
|
|
if((pSiS->VGAEngine != SIS_300_VGA) &&
|
|
(pSiS->VGAEngine != SIS_315_VGA))
|
|
return;
|
|
|
|
pSiS->SCLogQuiet = FALSE;
|
|
|
|
if(!(myext = CheckExtension(SISCTRL_PROTOCOL_NAME))) {
|
|
|
|
if(!(myctrl = xcalloc(sizeof(xSiSCtrlScreenTable), 1)))
|
|
return;
|
|
|
|
if(!(myext = AddExtension(SISCTRL_PROTOCOL_NAME, 0, 0,
|
|
SiSProcSiSCtrlDispatch,
|
|
SiSSProcSiSCtrlDispatch,
|
|
SiSCtrlResetProc,
|
|
StandardMinorOpcode))) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"Failed to add SISCTRL extension\n");
|
|
xfree(myctrl);
|
|
return;
|
|
}
|
|
|
|
myext->extPrivate = (pointer)myctrl;
|
|
|
|
myctrl->maxscreens = SISCTRL_MAX_SCREENS;
|
|
myctrl->version_major = version = SISCTRL_MAJOR_VERSION;
|
|
myctrl->version_minor = revision = SISCTRL_MINOR_VERSION;
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"Initialized SISCTRL extension version %d.%d\n",
|
|
version, revision);
|
|
|
|
} else {
|
|
|
|
if(!(myctrl = (xSiSCtrlScreenTable *)myext->extPrivate)) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"Internal error: Found SISCTRL extension with NULL-private!\n");
|
|
return;
|
|
}
|
|
|
|
version = myctrl->version_major;
|
|
revision = myctrl->version_minor;
|
|
}
|
|
|
|
if(pScrn->scrnIndex < myctrl->maxscreens) {
|
|
|
|
myctrl->HandleSiSDirectCommand[pScrn->scrnIndex] = SiSHandleSiSDirectCommand;
|
|
|
|
pSiS->SiSCtrlExtEntry = myext;
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"Registered screen %d with SISCTRL extension version %d.%d\n",
|
|
pScrn->scrnIndex, version, revision);
|
|
} else {
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"Screen number (%d) too high for SISCTRL extension %d.%d\n",
|
|
pScrn->scrnIndex, version, revision);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void
|
|
SiSCtrlExtUnregister(SISPtr pSiS, int index)
|
|
{
|
|
ExtensionEntry *myext;
|
|
xSiSCtrlScreenTable *myctrl;
|
|
|
|
if(!pSiS->SiSCtrlExtEntry) return;
|
|
|
|
/* Since CloseDownExtensions() is called before
|
|
* our CloseScreen(), we must not use the saved
|
|
* ptr here, but instead check for the extension.
|
|
*/
|
|
|
|
if((myext = CheckExtension(SISCTRL_PROTOCOL_NAME))) {
|
|
if((myctrl = (xSiSCtrlScreenTable *)myext->extPrivate)) {
|
|
myctrl->HandleSiSDirectCommand[index] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/***********************************
|
|
* Xv attribute interface *
|
|
***********************************/
|
|
|
|
#ifdef XV_SD_DEPRECATED
|
|
|
|
int
|
|
SISSetPortUtilAttribute(ScrnInfoPtr pScrn, Atom attribute,
|
|
INT32 value, SISPortPrivPtr pPriv)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
#ifdef SISDUALHEAD
|
|
SISEntPtr pSiSEnt = pSiS->entityPrivate;;
|
|
#endif
|
|
|
|
if(attribute == pSiS->xv_USD) {
|
|
if(pSiS->enablesisctrl) {
|
|
if(value == SIS_DIRECTKEY) {
|
|
pSiS->xv_sisdirectunlocked++;
|
|
} else if(pSiS->xv_sisdirectunlocked) {
|
|
pSiS->xv_sisdirectunlocked--;
|
|
}
|
|
} else {
|
|
pSiS->xv_sisdirectunlocked = 0;
|
|
}
|
|
} else if(attribute == pSiS->xv_SVF) {
|
|
#ifdef SISDUALHEAD
|
|
if(!pPriv->dualHeadMode)
|
|
#endif
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SISSwitchCRT2Type(pScrn, (ULong)value, FALSE);
|
|
SISUpdateVideoParms(pSiS, pPriv);
|
|
}
|
|
} else if(attribute == pSiS->xv_CT1) {
|
|
#ifdef SISDUALHEAD
|
|
if(!pPriv->dualHeadMode)
|
|
#endif
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SISSwitchCRT1Status(pScrn, (ULong)value, FALSE);
|
|
SISUpdateVideoParms(pSiS, pPriv);
|
|
}
|
|
} else if(attribute == pSiS->xv_RDT) {
|
|
#ifdef SISDUALHEAD
|
|
if(!pPriv->dualHeadMode)
|
|
#endif
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SISRedetectCRT2Devices(pScrn);
|
|
}
|
|
} else if(attribute == pSiS->xv_TAF) {
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetSISTVantiflicker(pScrn, (int)value);
|
|
}
|
|
} else if(attribute == pSiS->xv_TSA) {
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetSISTVsaturation(pScrn, (int)value);
|
|
}
|
|
} else if(attribute == pSiS->xv_TEE) {
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetSISTVedgeenhance(pScrn, (int)value);
|
|
}
|
|
} else if(attribute == pSiS->xv_CFI) {
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetSISTVcfilter(pScrn, value ? 1 : 0);
|
|
}
|
|
} else if(attribute == pSiS->xv_YFI) {
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetSISTVyfilter(pScrn, value);
|
|
}
|
|
} else if(attribute == pSiS->xv_COC) {
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetSISTVcolcalib(pScrn, (int)value, TRUE);
|
|
}
|
|
} else if(attribute == pSiS->xv_COF) {
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetSISTVcolcalib(pScrn, (int)value, FALSE);
|
|
}
|
|
} else if(attribute == pSiS->xv_TCO) {
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetCHTVcontrast(pScrn, (int)value);
|
|
}
|
|
} else if(attribute == pSiS->xv_TTE) {
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetCHTVtextenhance(pScrn, (int)value);
|
|
}
|
|
} else if(attribute == pSiS->xv_TCF) {
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetCHTVchromaflickerfilter(pScrn, (int)value);
|
|
}
|
|
} else if(attribute == pSiS->xv_TLF) {
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetCHTVlumaflickerfilter(pScrn, (int)value);
|
|
}
|
|
} else if(attribute == pSiS->xv_TCC) {
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetCHTVcvbscolor(pScrn, value ? 1 : 0);
|
|
}
|
|
} else if(attribute == pSiS->xv_OVR) {
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
pSiS->UseCHOverScan = -1;
|
|
pSiS->OptTVSOver = FALSE;
|
|
if(value == 3) {
|
|
if(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTSOVER) {
|
|
pSiS->OptTVSOver = TRUE;
|
|
}
|
|
pSiS->UseCHOverScan = 1;
|
|
} else if(value == 2) pSiS->UseCHOverScan = 1;
|
|
else if(value == 1) pSiS->UseCHOverScan = 0;
|
|
}
|
|
} else if(attribute == pSiS->xv_CMD) {
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
int result = 0;
|
|
pSiS->xv_sd_result = (value & 0xffffff00);
|
|
result = SISCheckModeIndexForCRT2Type(pScrn, (UShort)(value & 0xff),
|
|
(UShort)((value >> 8) & 0xff),
|
|
FALSE);
|
|
pSiS->xv_sd_result |= (result & 0xff);
|
|
}
|
|
} else if(attribute == pSiS->xv_SGA) {
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
Bool backup = pSiS->XvGamma;
|
|
Bool backup2 = pSiS->CRT2SepGamma;
|
|
pSiS->CRT1gamma = (value & 0x01) ? TRUE : FALSE;
|
|
pSiS->CRT2gamma = (value & 0x02) ? TRUE : FALSE;
|
|
#ifdef SISDUALHEAD
|
|
if(pPriv->dualHeadMode) {
|
|
pSiSEnt->CRT1gamma = pSiS->CRT1gamma;
|
|
pSiSEnt->CRT2gamma = pSiS->CRT2gamma;
|
|
}
|
|
#endif
|
|
if(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTSGRCRT2) {
|
|
pSiS->CRT2SepGamma = (value & 0x08) ? TRUE : FALSE;
|
|
if(pSiS->CRT2SepGamma != backup2) {
|
|
if(pSiS->CRT2SepGamma) {
|
|
SiS_UpdateGammaCRT2(pScrn);
|
|
}
|
|
#ifdef SISGAMMARAMP
|
|
else {
|
|
SISCalculateGammaRamp(pScrn->pScreen, pScrn);
|
|
}
|
|
#endif
|
|
/* ATTN: When disabling CRT2 sep gamma,
|
|
* as long as SISGAMMARAMP is not defined,
|
|
* application needs to reset palette using
|
|
* vidmodextension! (See SiS_SD_CANSETGAMMA)
|
|
*
|
|
* Note: Difference between setting gamma values
|
|
* for CRT1 and CRT2: For CRT1, driver only
|
|
* stores the values, but does nothing with them.
|
|
* For CRT2, the driver will IMMEDIATELY recalc
|
|
* the palette. App needs to calc gamma ramp
|
|
* itself for CRT1, and set it using the
|
|
* VidModExtention.
|
|
*/
|
|
}
|
|
} else pSiS->CRT2SepGamma = FALSE;
|
|
pSiS->XvGamma = (value & 0x04) ? TRUE : FALSE;
|
|
if(pSiS->VGAEngine == SIS_315_VGA) {
|
|
if(backup != pSiS->XvGamma) {
|
|
SiSUpdateXvGamma(pSiS, pPriv);
|
|
}
|
|
}
|
|
}
|
|
} else if(attribute == pSiS->xv_TXS) {
|
|
if((value < -16) || (value > 16)) return BadValue;
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetTVxscale(pScrn, value);
|
|
}
|
|
} else if(attribute == pSiS->xv_TYS) {
|
|
if((value < -4) || (value > 3)) return BadValue;
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
SiS_SetTVyscale(pScrn, value);
|
|
}
|
|
} else if(attribute == pSiS->xv_BRR) {
|
|
if((value < 100) || (value > 10000)) return BadValue;
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
pSiS->GammaBriR = value;
|
|
}
|
|
} else if(attribute == pSiS->xv_BRG) {
|
|
if((value < 100) || (value > 10000)) return BadValue;
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
pSiS->GammaBriG = value;
|
|
}
|
|
} else if(attribute == pSiS->xv_BRB) {
|
|
if((value < 100) || (value > 10000)) return BadValue;
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
pSiS->GammaBriB = value;
|
|
}
|
|
} else if(attribute == pSiS->xv_PBR) {
|
|
/* Nop */
|
|
} else if(attribute == pSiS->xv_PBG) {
|
|
/* Nop */
|
|
} else if(attribute == pSiS->xv_PBB) {
|
|
/* Nop */
|
|
} else if(attribute == pSiS->xv_BRR2) {
|
|
if((value < 100) || (value > 10000)) return BadValue;
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
#ifdef SISDUALHEAD
|
|
if(pPriv->dualHeadMode) pSiSEnt->GammaBriR = value;
|
|
#endif
|
|
}
|
|
} else if(attribute == pSiS->xv_BRG2) {
|
|
if((value < 100) || (value > 10000)) return BadValue;
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
#ifdef SISDUALHEAD
|
|
if(pPriv->dualHeadMode) pSiSEnt->GammaBriG = value;
|
|
#endif
|
|
}
|
|
} else if(attribute == pSiS->xv_BRB2) {
|
|
if((value < 100) || (value > 10000)) return BadValue;
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
#ifdef SISDUALHEAD
|
|
if(pPriv->dualHeadMode) pSiSEnt->GammaBriB = value;
|
|
#endif
|
|
}
|
|
} else if(attribute == pSiS->xv_PBR2) {
|
|
/* Nop */
|
|
} else if(attribute == pSiS->xv_PBG2) {
|
|
/* Nop */
|
|
} else if(attribute == pSiS->xv_PBB2) {
|
|
/* Nop */
|
|
} else if(attribute == pSiS->xv_GARC2) {
|
|
if((value < 100) || (value > 10000)) return BadValue;
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
pSiS->GammaR2 = (float)value / (float)1000;
|
|
SiS_UpdateGammaCRT2(pScrn);
|
|
}
|
|
} else if(attribute == pSiS->xv_GAGC2) {
|
|
if((value < 100) || (value > 10000)) return BadValue;
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
pSiS->GammaG2 = (float)value / (float)1000;
|
|
SiS_UpdateGammaCRT2(pScrn);
|
|
}
|
|
} else if(attribute == pSiS->xv_GABC2) {
|
|
if((value < 100) || (value > 10000)) return BadValue;
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
pSiS->GammaB2 = (float)value / (float)1000;
|
|
SiS_UpdateGammaCRT2(pScrn);
|
|
}
|
|
} else if(attribute == pSiS->xv_BRRC2) {
|
|
if((value < 100) || (value > 10000)) return BadValue;
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
pSiS->GammaBriR2 = value;
|
|
SiS_UpdateGammaCRT2(pScrn);
|
|
}
|
|
} else if(attribute == pSiS->xv_BRGC2) {
|
|
if((value < 100) || (value > 10000)) return BadValue;
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
pSiS->GammaBriG2 = value;
|
|
SiS_UpdateGammaCRT2(pScrn);
|
|
}
|
|
} else if(attribute == pSiS->xv_BRBC2) {
|
|
if((value < 100) || (value > 10000)) return BadValue;
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
pSiS->GammaBriB2 = value;
|
|
SiS_UpdateGammaCRT2(pScrn);
|
|
}
|
|
} else if(attribute == pSiS->xv_PBRC2) {
|
|
/* Nop */
|
|
} else if(attribute == pSiS->xv_PBGC2) {
|
|
/* Nop */
|
|
} else if(attribute == pSiS->xv_PBBC2) {
|
|
/* Nop */
|
|
} else if(attribute == pSiS->xv_SHC) {
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
Bool VisibleBackup = pSiS->HWCursorIsVisible;
|
|
pSiS->HideHWCursor = value ? TRUE : FALSE;
|
|
if(pSiS->CursorInfoPtr) {
|
|
if(VisibleBackup) {
|
|
if(value) {
|
|
(pSiS->CursorInfoPtr->HideCursor)(pScrn);
|
|
} else {
|
|
(pSiS->CursorInfoPtr->ShowCursor)(pScrn);
|
|
}
|
|
}
|
|
pSiS->HWCursorIsVisible = VisibleBackup;
|
|
}
|
|
}
|
|
} else if(attribute == pSiS->xv_PMD) {
|
|
if(pSiS->xv_sisdirectunlocked) {
|
|
if(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTSCALE) {
|
|
if(value & 0x01) pSiS->SiS_Pr->UsePanelScaler = -1;
|
|
else if(value & 0x02) pSiS->SiS_Pr->UsePanelScaler = 1;
|
|
else pSiS->SiS_Pr->UsePanelScaler = 0;
|
|
if(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTCENTER) {
|
|
if(value & 0x04) pSiS->SiS_Pr->CenterScreen = -1;
|
|
else if(value & 0x08) pSiS->SiS_Pr->CenterScreen = 1;
|
|
else pSiS->SiS_Pr->CenterScreen = 0;
|
|
}
|
|
}
|
|
}
|
|
#ifdef TWDEBUG
|
|
} else if(attribute == pSiS->xv_STR) {
|
|
ULong port;
|
|
CARD8 reg;
|
|
switch((value & 0xff000000) >> 24) {
|
|
case 0x00: port = SISSR; break;
|
|
case 0x01: port = SISPART1; break;
|
|
case 0x02: port = SISPART2; break;
|
|
case 0x03: port = SISPART3; break;
|
|
case 0x04: port = SISPART4; break;
|
|
case 0x05: port = SISCR; break;
|
|
case 0x06: port = SISVID; break;
|
|
default: return BadValue;
|
|
}
|
|
outSISIDXREG(port,((value & 0x00ff0000) >> 16), ((value & 0x0000ff00) >> 8));
|
|
inSISIDXREG(port, ((value & 0x00ff0000) >> 16), reg);
|
|
xf86DrvMsg(0, 0, "SetREG %x -> %x -> %x\n", ((value & 0x00ff0000) >> 16), ((value & 0x0000ff00) >> 8), reg);
|
|
#endif
|
|
} else {
|
|
return BadMatch;
|
|
}
|
|
|
|
return Success;
|
|
}
|
|
|
|
int
|
|
SISGetPortUtilAttribute(ScrnInfoPtr pScrn, Atom attribute,
|
|
INT32 *value, SISPortPrivPtr pPriv)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
#ifdef SISDUALHEAD
|
|
SISEntPtr pSiSEnt = pSiS->entityPrivate;;
|
|
#endif
|
|
|
|
if(attribute == pSiS->xv_QVF) {
|
|
*value = pSiS->VBFlags;
|
|
} else if(attribute == pSiS->xv_GDV) {
|
|
*value = SISDRIVERIVERSION;
|
|
} else if(attribute == pSiS->xv_GHI) {
|
|
*value = (pSiS->ChipFlags & 0xffff) | (pSiS->ChipType << 16) | (pSiS->ChipRev << 24);
|
|
} else if(attribute == pSiS->xv_GBI) {
|
|
*value = (pSiS->PciBus << 16) | (pSiS->PciDevice << 8) | pSiS->PciFunc;
|
|
} else if(attribute == pSiS->xv_QVV) {
|
|
*value = SIS_VBFlagsVersion;
|
|
} else if(attribute == pSiS->xv_QDD) {
|
|
*value = pSiS->detectedCRT2Devices;
|
|
} else if(attribute == pSiS->xv_CT1) {
|
|
*value = pSiS->CRT1isoff ? 0 : 1;
|
|
} else if(attribute == pSiS->xv_GSF) {
|
|
*value = pSiS->SiS_SD_Flags;
|
|
} else if(attribute == pSiS->xv_GSF2) {
|
|
*value = pSiS->SiS_SD2_Flags;
|
|
} else if(attribute == pSiS->xv_USD) {
|
|
*value = pSiS->xv_sisdirectunlocked;
|
|
} else if(attribute == pSiS->xv_TAF) {
|
|
*value = SiS_GetSISTVantiflicker(pScrn);
|
|
} else if(attribute == pSiS->xv_TSA) {
|
|
*value = SiS_GetSISTVsaturation(pScrn);
|
|
} else if(attribute == pSiS->xv_TEE) {
|
|
*value = SiS_GetSISTVedgeenhance(pScrn);
|
|
} else if(attribute == pSiS->xv_CFI) {
|
|
*value = SiS_GetSISTVcfilter(pScrn);
|
|
} else if(attribute == pSiS->xv_YFI) {
|
|
*value = SiS_GetSISTVyfilter(pScrn);
|
|
} else if(attribute == pSiS->xv_COC) {
|
|
*value = SiS_GetSISTVcolcalib(pScrn, TRUE);
|
|
} else if(attribute == pSiS->xv_COF) {
|
|
*value = SiS_GetSISTVcolcalib(pScrn, FALSE);
|
|
} else if(attribute == pSiS->xv_TCO) {
|
|
*value = SiS_GetCHTVcontrast(pScrn);
|
|
} else if(attribute == pSiS->xv_TTE) {
|
|
*value = SiS_GetCHTVtextenhance(pScrn);
|
|
} else if(attribute == pSiS->xv_TCF) {
|
|
*value = SiS_GetCHTVchromaflickerfilter(pScrn);
|
|
} else if(attribute == pSiS->xv_TLF) {
|
|
*value = SiS_GetCHTVlumaflickerfilter(pScrn);
|
|
} else if(attribute == pSiS->xv_TCC) {
|
|
*value = SiS_GetCHTVcvbscolor(pScrn);
|
|
} else if(attribute == pSiS->xv_CMDR) {
|
|
*value = pSiS->xv_sd_result;
|
|
} else if(attribute == pSiS->xv_OVR) {
|
|
/* Changing of CRT2 settings not supported in DHM! */
|
|
*value = 0;
|
|
if(pSiS->OptTVSOver == 1) *value = 3;
|
|
else if(pSiS->UseCHOverScan == 1) *value = 2;
|
|
else if(pSiS->UseCHOverScan == 0) *value = 1;
|
|
} else if(attribute == pSiS->xv_SGA) {
|
|
*value = 0;
|
|
#ifdef SISDUALHEAD
|
|
if(pPriv->dualHeadMode) {
|
|
if(pSiSEnt->CRT1gamma) *value |= 0x01;
|
|
if(pSiSEnt->CRT2gamma) *value |= 0x02;
|
|
} else {
|
|
#endif
|
|
if(pSiS->CRT1gamma) *value |= 0x01;
|
|
if(pSiS->CRT2gamma) *value |= 0x02;
|
|
if(pSiS->CRT2SepGamma) *value |= 0x08;
|
|
#ifdef SISDUALHEAD
|
|
}
|
|
#endif
|
|
if(pSiS->XvGamma) *value |= 0x04;
|
|
} else if(attribute == pSiS->xv_TXS) {
|
|
*value = SiS_GetTVxscale(pScrn);
|
|
} else if(attribute == pSiS->xv_TYS) {
|
|
*value = SiS_GetTVyscale(pScrn);
|
|
} else if(attribute == pSiS->xv_GSS) {
|
|
*value = (pScrn->virtualX << 16) | pScrn->virtualY;
|
|
} else if(attribute == pSiS->xv_BRR) {
|
|
*value = pSiS->GammaBriR;
|
|
} else if(attribute == pSiS->xv_BRG) {
|
|
*value = pSiS->GammaBriG;
|
|
} else if(attribute == pSiS->xv_BRB) {
|
|
*value = pSiS->GammaBriB;
|
|
} else if(attribute == pSiS->xv_PBR) {
|
|
*value = 1000;
|
|
} else if(attribute == pSiS->xv_PBG) {
|
|
*value = 1000;
|
|
} else if(attribute == pSiS->xv_PBB) {
|
|
*value = 1000;
|
|
} else if(attribute == pSiS->xv_BRR2) {
|
|
#ifdef SISDUALHEAD
|
|
if(pPriv->dualHeadMode) *value = pSiSEnt->GammaBriR;
|
|
else
|
|
#endif
|
|
*value = pSiS->GammaBriR;
|
|
} else if(attribute == pSiS->xv_BRG2) {
|
|
#ifdef SISDUALHEAD
|
|
if(pPriv->dualHeadMode) *value = pSiSEnt->GammaBriG;
|
|
else
|
|
#endif
|
|
*value = pSiS->GammaBriG;
|
|
} else if(attribute == pSiS->xv_BRB2) {
|
|
#ifdef SISDUALHEAD
|
|
if(pPriv->dualHeadMode) *value = pSiSEnt->GammaBriB;
|
|
else
|
|
#endif
|
|
*value = pSiS->GammaBriB;
|
|
} else if(attribute == pSiS->xv_PBR2) {
|
|
*value = 1000;
|
|
} else if(attribute == pSiS->xv_PBG2) {
|
|
*value = 1000;
|
|
} else if(attribute == pSiS->xv_PBB2) {
|
|
*value = 1000;
|
|
} else if(attribute == pSiS->xv_GARC2) {
|
|
*value = (int)(pSiS->GammaR2 * 1000);
|
|
} else if(attribute == pSiS->xv_GAGC2) {
|
|
*value = (int)(pSiS->GammaG2 * 1000);
|
|
} else if(attribute == pSiS->xv_GABC2) {
|
|
*value = (int)(pSiS->GammaB2 * 1000);
|
|
} else if(attribute == pSiS->xv_BRRC2) {
|
|
*value = pSiS->GammaBriR2;
|
|
} else if(attribute == pSiS->xv_BRGC2) {
|
|
*value = pSiS->GammaBriG2;
|
|
} else if(attribute == pSiS->xv_BRBC2) {
|
|
*value = pSiS->GammaBriB2;
|
|
} else if(attribute == pSiS->xv_PBRC2) {
|
|
*value = 1000;
|
|
} else if(attribute == pSiS->xv_PBGC2) {
|
|
*value = 1000;
|
|
} else if(attribute == pSiS->xv_PBBC2) {
|
|
*value = 1000;
|
|
} else if(attribute == pSiS->xv_SHC) {
|
|
*value = pSiS->HideHWCursor ? 1 : 0;
|
|
} else if(attribute == pSiS->xv_PMD) {
|
|
*value = 0;
|
|
if(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTSCALE) {
|
|
switch(pSiS->SiS_Pr->UsePanelScaler) {
|
|
case -1: *value |= 0x01; break;
|
|
case 1: *value |= 0x02; break;
|
|
}
|
|
if(pSiS->SiS_SD_Flags & SiS_SD_SUPPORTCENTER) {
|
|
switch(pSiS->SiS_Pr->CenterScreen) {
|
|
case -1: *value |= 0x04; break;
|
|
case 1: *value |= 0x08; break;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
return BadMatch;
|
|
}
|
|
|
|
return Success;
|
|
}
|
|
|
|
#endif /* XV_SD_DEPRECATED */
|
|
|