3 * SiS hardware cursor handling
5 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1) Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2) Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3) All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: "This product includes
17 * software developed by Thomas Winischhofer, Vienna, Austria."
18 * 4) The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * Author: Thomas Winischhofer <thomas@winischhofer.net>
34 * Idea based on code by Can-Ru Yeou, SiS Inc.
39 #include "xf86PciInfo.h"
40 #include "cursorstr.h"
45 #include "sis_cursor.h"
48 #define SIS300_USE_ARGB16
50 #undef SIS300_USE_ARGB16
53 extern void SISWaitRetraceCRT1(ScrnInfoPtr pScrn
);
54 extern void SISWaitRetraceCRT2(ScrnInfoPtr pScrn
);
56 /* Helper function for Xabre to convert mono image to ARGB */
57 /* The Xabre's cursor engine for CRT2 is buggy and can't
58 * handle mono cursors. We therefore convert the mono image
62 SiSXConvertMono2ARGB(SISPtr pSiS
)
64 unsigned char *src
= pSiS
->CurMonoSrc
;
65 CARD32
*dest
= pSiS
->CurARGBDest
;
67 CARD32 fg
= pSiS
->CurFGCol
| 0xff000000;
68 CARD32 bg
= pSiS
->CurBGCol
| 0xff000000;
71 if(!dest
|| !src
) return;
73 for(i
= 0; i
< 64; i
++) {
74 for(j
= 0; j
< 8; j
++) {
75 chunk
= *(src
+ 8); mask
= *src
++;
76 for(k
= 128; k
!= 0; k
>>= 1) {
77 if(mask
& k
) *dest
++ = 0x00000000;
78 else if(chunk
& k
) *dest
++ = fg
;
87 SiSHideCursor(ScrnInfoPtr pScrn
)
89 SISPtr pSiS
= SISPTR(pScrn
);
90 unsigned char sridx
, cridx
;
92 sridx
= inSISREG(SISSR
); cridx
= inSISREG(SISCR
);
95 sisSaveUnlockExtRegisterLock(pSiS
, NULL
, NULL
);
98 andSISIDXREG(SISSR
, 0x06, 0xBF);
100 outSISREG(SISSR
, sridx
); outSISREG(SISCR
, cridx
);
104 SiS300HideCursor(ScrnInfoPtr pScrn
)
106 SISPtr pSiS
= SISPTR(pScrn
);
109 if(pSiS
->DualHeadMode
&& (!pSiS
->ForceCursorOff
)) {
110 if(pSiS
->SecondHead
) {
111 /* Head 2 is always CRT1 */
112 sis300DisableHWCursor()
113 sis300SetCursorPositionY(2000, 0)
115 /* Head 1 is always CRT2 */
116 sis301DisableHWCursor()
117 sis301SetCursorPositionY(2000, 0)
121 sis300DisableHWCursor()
122 sis300SetCursorPositionY(2000, 0)
123 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
124 sis301DisableHWCursor()
125 sis301SetCursorPositionY(2000, 0)
133 SiS310HideCursor(ScrnInfoPtr pScrn
)
135 SISPtr pSiS
= SISPTR(pScrn
);
137 pSiS
->HWCursorIsVisible
= FALSE
;
140 if(pSiS
->DualHeadMode
&& (!pSiS
->ForceCursorOff
)) {
141 if(pSiS
->SecondHead
) {
142 /* Head 2 is always CRT1 */
143 sis310DisableHWCursor()
144 sis310SetCursorPositionY(2000, 0)
146 /* Head 1 is always CRT2 */
147 sis301DisableHWCursor310()
148 sis301SetCursorPositionY310(2000, 0)
152 sis310DisableHWCursor()
153 sis310SetCursorPositionY(2000, 0)
154 if(pSiS
->VBFlags
& VB_VIDEOBRIDGE
) {
155 sis301DisableHWCursor310()
156 sis301SetCursorPositionY310(2000, 0)
164 SiSShowCursor(ScrnInfoPtr pScrn
)
166 SISPtr pSiS
= SISPTR(pScrn
);
167 unsigned char sridx
, cridx
;
169 /* Backup current indices of SR and CR since we run async:ly
170 * and might be interrupting an on-going register read/write
172 sridx
= inSISREG(SISSR
); cridx
= inSISREG(SISCR
);
175 sisSaveUnlockExtRegisterLock(pSiS
, NULL
, NULL
);
178 orSISIDXREG(SISSR
, 0x06, 0x40);
180 outSISREG(SISSR
, sridx
); outSISREG(SISCR
, cridx
);
184 SiS300ShowCursor(ScrnInfoPtr pScrn
)
186 SISPtr pSiS
= SISPTR(pScrn
);
189 if(pSiS
->DualHeadMode
) {
190 if(pSiS
->SecondHead
) {
191 /* Head 2 is always CRT1 */
192 if(pSiS
->UseHWARGBCursor
) {
193 #ifdef SIS300_USE_ARGB16
194 sis300EnableHWARGB16Cursor()
196 sis300EnableHWARGBCursor()
199 sis300EnableHWCursor()
202 /* Head 1 is always CRT2 */
203 if(pSiS
->UseHWARGBCursor
) {
204 #ifdef SIS300_USE_ARGB16
205 sis301EnableHWARGB16Cursor()
207 sis301EnableHWARGBCursor()
210 sis301EnableHWCursor()
215 if(pSiS
->UseHWARGBCursor
) {
216 #ifdef SIS300_USE_ARGB16
217 sis300EnableHWARGB16Cursor()
219 sis300EnableHWARGBCursor()
221 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
222 #ifdef SIS300_USE_ARGB16
223 sis301EnableHWARGB16Cursor()
225 sis301EnableHWARGBCursor()
229 sis300EnableHWCursor()
230 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
231 sis301EnableHWCursor()
240 SiS310ShowCursor(ScrnInfoPtr pScrn
)
242 SISPtr pSiS
= SISPTR(pScrn
);
244 if(pSiS
->HideHWCursor
) {
245 SiS310HideCursor(pScrn
);
246 pSiS
->HWCursorIsVisible
= TRUE
;
250 pSiS
->HWCursorIsVisible
= TRUE
;
253 if(pSiS
->DualHeadMode
) {
254 if(pSiS
->SecondHead
) {
255 /* Head 2 is always CRT1 */
256 if(pSiS
->UseHWARGBCursor
) {
257 sis310EnableHWARGBCursor()
259 sis310EnableHWCursor()
262 /* Head 1 is always CRT2 */
263 if(pSiS
->ChipFlags
& SiSCF_CRT2HWCKaputt
) {
264 sis301EnableHWCursor330()
266 if(pSiS
->UseHWARGBCursor
) {
267 sis301EnableHWARGBCursor310()
269 sis301EnableHWCursor310()
275 if(pSiS
->ChipFlags
& SiSCF_CRT2HWCKaputt
) {
276 if(pSiS
->UseHWARGBCursor
) {
277 sis310EnableHWARGBCursor()
279 sis310EnableHWCursor()
281 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
282 sis301EnableHWCursor330()
285 if(pSiS
->UseHWARGBCursor
) {
286 sis310EnableHWARGBCursor()
287 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
288 sis301EnableHWARGBCursor310()
291 sis310EnableHWCursor()
292 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
293 sis301EnableHWCursor310()
303 SiSSetCursorPosition(ScrnInfoPtr pScrn
, int x
, int y
)
305 SISPtr pSiS
= SISPTR(pScrn
);
306 DisplayModePtr mode
= pSiS
->CurrentLayout
.mode
;
307 unsigned char x_preset
= 0;
308 unsigned char y_preset
= 0;
310 unsigned char sridx
, cridx
;
312 sridx
= inSISREG(SISSR
); cridx
= inSISREG(SISCR
);
315 sisSaveUnlockExtRegisterLock(pSiS
, NULL
, NULL
);
328 if(mode
->Flags
& V_INTERLACE
) y
/= 2;
329 else if(mode
->Flags
& V_DBLSCAN
) y
*= 2;
331 outSISIDXREG(SISSR
, 0x1A, x
& 0xff);
332 outSISIDXREG(SISSR
, 0x1B, (x
& 0xff00) >> 8);
333 outSISIDXREG(SISSR
, 0x1D, y
& 0xff);
335 inSISIDXREG(SISSR
, 0x1E, temp
);
337 outSISIDXREG(SISSR
, 0x1E, temp
| ((y
>> 8) & 0x07));
339 outSISIDXREG(SISSR
, 0x1C, x_preset
);
340 outSISIDXREG(SISSR
, 0x1F, y_preset
);
342 outSISREG(SISSR
, sridx
); outSISREG(SISCR
, cridx
);
347 SiSSetCursorPositionMerged(ScrnInfoPtr pScrn1
, int x
, int y
)
349 SISPtr pSiS
= SISPTR(pScrn1
);
350 ScrnInfoPtr pScrn2
= pSiS
->CRT2pScrn
;
351 DisplayModePtr mode1
= CDMPTR
->CRT1
;
352 DisplayModePtr mode2
= CDMPTR
->CRT2
;
353 unsigned short x1_preset
= 0, x2_preset
= 0;
354 unsigned short y1_preset
= 0, y2_preset
= 0;
355 unsigned short maxpreset
;
358 x
+= pScrn1
->frameX0
;
359 y
+= pScrn1
->frameY0
;
361 x1
= x
- pSiS
->CRT1frameX0
;
362 y1
= y
- pSiS
->CRT1frameY0
;
364 x2
= x
- pScrn2
->frameX0
;
365 y2
= y
- pScrn2
->frameY0
;
368 if((pSiS
->VGAEngine
== SIS_300_VGA
) && (pSiS
->UseHWARGBCursor
)) maxpreset
= 31;
372 if(x1_preset
> maxpreset
) x1_preset
= maxpreset
;
377 if(y1_preset
> maxpreset
) y1_preset
= maxpreset
;
382 if(x2_preset
> maxpreset
) x2_preset
= maxpreset
;
387 if(y2_preset
> maxpreset
) y2_preset
= maxpreset
;
391 if(mode1
->Flags
& V_INTERLACE
) { y1
/= 2; y1_preset
/= 2; }
392 else if(mode1
->Flags
& V_DBLSCAN
) { y1
*= 2; y1_preset
*= 2; }
394 if(mode2
->Flags
& V_INTERLACE
) { y2
/= 2; y2_preset
/= 2; }
395 else if(mode2
->Flags
& V_DBLSCAN
) { y2
*= 2; y2_preset
*= 2; }
397 /* Work around bug in Cursor engine */
398 if(x1
> mode1
->HDisplay
) { y1
= 2000; y1_preset
= 0; }
399 if(x2
> mode2
->HDisplay
) { y2
= 2000; y2_preset
= 0; }
401 if(pSiS
->VGAEngine
== SIS_300_VGA
) {
402 sis300SetCursorPositionX(x1
, x1_preset
)
403 sis300SetCursorPositionY(y1
, y1_preset
)
404 sis301SetCursorPositionX(x2
+ 13, x2_preset
)
405 sis301SetCursorPositionY(y2
, y2_preset
)
407 sis310SetCursorPositionX(x1
, x1_preset
)
408 sis310SetCursorPositionY(y1
, y1_preset
)
409 sis301SetCursorPositionX310(x2
+ 17, x2_preset
)
410 sis301SetCursorPositionY310(y2
, y2_preset
)
416 SiS300SetCursorPosition(ScrnInfoPtr pScrn
, int x
, int y
)
418 SISPtr pSiS
= SISPTR(pScrn
);
419 DisplayModePtr mode
= pSiS
->CurrentLayout
.mode
; /* pScrn->currentMode; */
420 unsigned short x_preset
= 0;
421 unsigned short y_preset
= 0;
425 SiSSetCursorPositionMerged(pScrn
, x
, y
);
439 if(mode
->Flags
& V_INTERLACE
) y
/= 2;
440 else if(mode
->Flags
& V_DBLSCAN
) y
*= 2;
443 if(pSiS
->DualHeadMode
) {
444 if(pSiS
->SecondHead
) {
445 /* Head 2 is always CRT1 */
446 sis300SetCursorPositionX(x
, x_preset
)
447 sis300SetCursorPositionY(y
, y_preset
)
449 /* Head 1 is always CRT2 */
450 sis301SetCursorPositionX(x
+ 13, x_preset
)
451 sis301SetCursorPositionY(y
, y_preset
)
455 sis300SetCursorPositionX(x
, x_preset
)
456 sis300SetCursorPositionY(y
, y_preset
)
457 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
458 sis301SetCursorPositionX(x
+ 13, x_preset
)
459 sis301SetCursorPositionY(y
, y_preset
)
467 SiS310SetCursorPosition(ScrnInfoPtr pScrn
, int x
, int y
)
469 SISPtr pSiS
= SISPTR(pScrn
);
470 DisplayModePtr mode
= pSiS
->CurrentLayout
.mode
;
471 unsigned short x_preset
= 0;
472 unsigned short y_preset
= 0;
476 SiSSetCursorPositionMerged(pScrn
, x
, y
);
490 if(mode
->Flags
& V_INTERLACE
) y
/= 2;
491 else if(mode
->Flags
& V_DBLSCAN
) y
*= 2;
494 if(pSiS
->DualHeadMode
) {
495 if(pSiS
->SecondHead
) {
496 /* Head 2 is always CRT1 */
497 sis310SetCursorPositionX(x
, x_preset
)
498 sis310SetCursorPositionY(y
, y_preset
)
500 /* Head 1 is always CRT2 */
501 sis301SetCursorPositionX310(x
+ 17, x_preset
)
502 sis301SetCursorPositionY310(y
, y_preset
)
506 sis310SetCursorPositionX(x
, x_preset
)
507 sis310SetCursorPositionY(y
, y_preset
)
508 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
509 sis301SetCursorPositionX310(x
+ 17, x_preset
)
510 sis301SetCursorPositionY310(y
, y_preset
)
519 SiSSetCursorColors(ScrnInfoPtr pScrn
, int bg
, int fg
)
521 SISPtr pSiS
= SISPTR(pScrn
);
522 unsigned char f_red
, f_green
, f_blue
;
523 unsigned char b_red
, b_green
, b_blue
;
524 unsigned char sridx
, cridx
;
526 sridx
= inSISREG(SISSR
); cridx
= inSISREG(SISCR
);
529 sisSaveUnlockExtRegisterLock(pSiS
, NULL
, NULL
);
532 f_red
= (fg
& 0x00FF0000) >> (16+2);
533 f_green
= (fg
& 0x0000FF00) >> (8+2);
534 f_blue
= (fg
& 0x000000FF) >> 2;
535 b_red
= (bg
& 0x00FF0000) >> (16+2);
536 b_green
= (bg
& 0x0000FF00) >> (8+2);
537 b_blue
= (bg
& 0x000000FF) >> 2;
539 outSISIDXREG(SISSR
, 0x14, b_red
);
540 outSISIDXREG(SISSR
, 0x15, b_green
);
541 outSISIDXREG(SISSR
, 0x16, b_blue
);
542 outSISIDXREG(SISSR
, 0x17, f_red
);
543 outSISIDXREG(SISSR
, 0x18, f_green
);
544 outSISIDXREG(SISSR
, 0x19, f_blue
);
546 outSISREG(SISSR
, sridx
); outSISREG(SISCR
, cridx
);
550 SiS300SetCursorColors(ScrnInfoPtr pScrn
, int bg
, int fg
)
552 SISPtr pSiS
= SISPTR(pScrn
);
554 if(pSiS
->UseHWARGBCursor
) return;
557 if(pSiS
->DualHeadMode
) {
558 if(pSiS
->SecondHead
) {
559 /* Head 2 is always CRT1 */
560 sis300SetCursorBGColor(bg
)
561 sis300SetCursorFGColor(fg
)
563 /* Head 1 is always CRT2 */
564 sis301SetCursorBGColor(bg
)
565 sis301SetCursorFGColor(fg
)
569 sis300SetCursorBGColor(bg
)
570 sis300SetCursorFGColor(fg
)
571 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
572 sis301SetCursorBGColor(bg
)
573 sis301SetCursorFGColor(fg
)
581 SiS310SetCursorColors(ScrnInfoPtr pScrn
, int bg
, int fg
)
583 SISPtr pSiS
= SISPTR(pScrn
);
585 if(pSiS
->UseHWARGBCursor
) return;
588 if(pSiS
->DualHeadMode
) {
589 if(pSiS
->SecondHead
) {
590 /* Head 2 is always CRT1 */
591 sis310SetCursorBGColor(bg
)
592 sis310SetCursorFGColor(fg
)
594 /* Head 1 is always CRT2 */
595 if(pSiS
->ChipFlags
& SiSCF_CRT2HWCKaputt
) {
596 if((fg
!= pSiS
->CurFGCol
) || (bg
!= pSiS
->CurBGCol
)) {
599 SiSXConvertMono2ARGB(pSiS
);
602 sis301SetCursorBGColor310(bg
)
603 sis301SetCursorFGColor310(fg
)
608 sis310SetCursorBGColor(bg
)
609 sis310SetCursorFGColor(fg
)
611 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
612 if(pSiS
->ChipFlags
& SiSCF_CRT2HWCKaputt
) {
613 if((fg
!= pSiS
->CurFGCol
) || (bg
!= pSiS
->CurBGCol
)) {
616 SiSXConvertMono2ARGB(pSiS
);
619 sis301SetCursorBGColor310(bg
)
620 sis301SetCursorFGColor310(fg
)
629 SiSLoadCursorImage(ScrnInfoPtr pScrn
, unsigned char *src
)
631 SISPtr pSiS
= SISPTR(pScrn
);
632 DisplayModePtr mode
= pSiS
->CurrentLayout
.mode
;
635 unsigned char sridx
, cridx
;
637 sridx
= inSISREG(SISSR
); cridx
= inSISREG(SISCR
);
640 sisSaveUnlockExtRegisterLock(pSiS
, NULL
, NULL
);
643 cursor_addr
= pScrn
->videoRam
- 1;
644 if(mode
->Flags
& V_DBLSCAN
) {
646 for(i
= 0; i
< 32; i
++) {
647 memcpy((unsigned char *)pSiS
->FbBase
+ (cursor_addr
* 1024) + (32 * i
),
649 memcpy((unsigned char *)pSiS
->FbBase
+ (cursor_addr
* 1024) + (32 * i
) + 16,
653 memcpy((unsigned char *)pSiS
->FbBase
+ (cursor_addr
* 1024), src
, 1024);
656 /* copy bits [21:18] into the top bits of SR38 */
657 inSISIDXREG(SISSR
, 0x38, temp
);
659 outSISIDXREG(SISSR
, 0x38, temp
| ((cursor_addr
& 0xF00) >> 4));
661 if(pSiS
->Chipset
== PCI_CHIP_SIS530
) {
662 /* store the bit [22] to SR3E */
663 if(cursor_addr
& 0x1000) {
664 orSISIDXREG(SISSR
, 0x3E, 0x04);
666 andSISIDXREG(SISSR
, 0x3E, ~0x04);
670 /* set HW cursor pattern, use pattern 0xF */
671 orSISIDXREG(SISSR
, 0x1E, 0xF0);
673 /* disable the hardware cursor side pattern */
674 andSISIDXREG(SISSR
, 0x1E, 0xF7);
676 outSISREG(SISSR
, sridx
); outSISREG(SISCR
, cridx
);
680 SiS300LoadCursorImage(ScrnInfoPtr pScrn
, unsigned char *src
)
682 SISPtr pSiS
= SISPTR(pScrn
);
684 CARD32 status1
= 0, status2
= 0;
685 unsigned char *dest
= pSiS
->FbBase
;
686 BOOLEAN sizedouble
= FALSE
;
688 SISEntPtr pSiSEnt
= pSiS
->entityPrivate
;
693 if((CDMPTR
->CRT1
->Flags
& V_DBLSCAN
) && (CDMPTR
->CRT2
->Flags
& V_DBLSCAN
)) {
698 if(pSiS
->CurrentLayout
.mode
->Flags
& V_DBLSCAN
) {
702 cursor_addr
= pScrn
->videoRam
- pSiS
->cursorOffset
- (pSiS
->CursorSize
/1024); /* 1K boundary */
705 /* TW: Use the global (real) FbBase in DHM */
706 if(pSiS
->DualHeadMode
) dest
= pSiSEnt
->FbBase
;
711 for(i
= 0; i
< 32; i
++) {
712 memcpy((unsigned char *)dest
+ (cursor_addr
* 1024) + (32 * i
),
714 memcpy((unsigned char *)dest
+ (cursor_addr
* 1024) + (32 * i
) + 16,
718 memcpy((unsigned char *)dest
+ (cursor_addr
* 1024), src
, 1024);
721 if(pSiS
->UseHWARGBCursor
) {
722 if(pSiS
->VBFlags
& DISPTYPE_CRT1
) {
723 status1
= sis300GetCursorStatus
;
724 sis300DisableHWCursor()
725 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
726 status2
= sis301GetCursorStatus
;
727 sis301DisableHWCursor()
729 SISWaitRetraceCRT1(pScrn
);
730 sis300SwitchToMONOCursor();
731 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
732 SISWaitRetraceCRT2(pScrn
);
733 sis301SwitchToMONOCursor();
737 sis300SetCursorAddress(cursor_addr
);
738 if(status1
) sis300SetCursorStatus(status1
)
740 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
741 if((pSiS
->UseHWARGBCursor
) && (!pSiS
->VBFlags
& DISPTYPE_CRT1
)) {
742 status2
= sis301GetCursorStatus
;
743 sis301DisableHWCursor()
744 SISWaitRetraceCRT2(pScrn
);
745 sis301SwitchToMONOCursor();
747 sis301SetCursorAddress(cursor_addr
)
748 if(status2
) sis301SetCursorStatus(status2
)
751 pSiS
->UseHWARGBCursor
= FALSE
;
755 SiS310LoadCursorImage(ScrnInfoPtr pScrn
, unsigned char *src
)
757 SISPtr pSiS
= SISPTR(pScrn
);
758 unsigned long cursor_addr
, cursor_addr2
= 0;
759 CARD32 status1
= 0, status2
= 0;
760 unsigned char *dest
= pSiS
->FbBase
;
761 BOOLEAN sizedouble
= FALSE
;
764 SISEntPtr pSiSEnt
= pSiS
->entityPrivate
;
766 if(pSiS
->DualHeadMode
) {
767 pSiSEnt
->HWCursorMBufNum
^= 1;
768 bufnum
= 1 << pSiSEnt
->HWCursorMBufNum
;
771 pSiS
->HWCursorMBufNum
^= 1;
772 bufnum
= 1 << pSiS
->HWCursorMBufNum
;
779 if((CDMPTR
->CRT1
->Flags
& V_DBLSCAN
) && (CDMPTR
->CRT2
->Flags
& V_DBLSCAN
)) {
784 if(pSiS
->CurrentLayout
.mode
->Flags
& V_DBLSCAN
) {
789 /* Use the global (real) FbBase in DHM */
790 if(pSiS
->DualHeadMode
) dest
= pSiSEnt
->FbBase
;
793 if(pSiS
->ChipFlags
& SiSCF_CRT2HWCKaputt
) {
794 cursor_addr
= pScrn
->videoRam
- pSiS
->cursorOffset
- (pSiS
->CursorSize
/1024);
796 cursor_addr
= pScrn
->videoRam
- pSiS
->cursorOffset
- ((pSiS
->CursorSize
/1024) * bufnum
);
801 for(i
= 0; i
< 32; i
++) {
802 memcpy((unsigned char *)dest
+ (cursor_addr
* 1024) + (32 * i
),
804 memcpy((unsigned char *)dest
+ (cursor_addr
* 1024) + (32 * i
) + 16,
808 memcpy((unsigned char *)dest
+ (cursor_addr
* 1024), src
, 1024);
811 if(pSiS
->ChipFlags
& SiSCF_CRT2HWCKaputt
) {
813 /* Convert Mono image to color image */
815 cursor_addr2
= pScrn
->videoRam
- pSiS
->cursorOffset
- ((pSiS
->CursorSize
/1024) * 2);
817 pSiS
->CurMonoSrc
= (unsigned char *)dest
+ (cursor_addr
* 1024);
818 pSiS
->CurARGBDest
= (CARD32
*)((unsigned char *)dest
+ (cursor_addr2
* 1024));
820 SiSXConvertMono2ARGB(pSiS
);
822 if(pSiS
->UseHWARGBCursor
) {
823 if(pSiS
->VBFlags
& DISPTYPE_CRT1
) {
824 status1
= sis310GetCursorStatus
;
825 sis310DisableHWCursor();
826 SISWaitRetraceCRT1(pScrn
);
827 sis310SwitchToMONOCursor();
833 if(pSiS
->UseHWARGBCursor
) {
834 if(pSiS
->VBFlags
& DISPTYPE_CRT1
) {
835 status1
= sis310GetCursorStatus
;
836 sis310DisableHWCursor()
837 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
838 status2
= sis301GetCursorStatus310
;
839 sis301DisableHWCursor310()
841 SISWaitRetraceCRT1(pScrn
);
842 sis310SwitchToMONOCursor();
843 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
844 SISWaitRetraceCRT2(pScrn
);
845 sis301SwitchToMONOCursor310();
848 } else if(pSiS
->Chipset
== PCI_CHIP_SIS315H
) {
849 if(pSiS
->VBFlags
& DISPTYPE_CRT1
) {
850 SISWaitRetraceCRT1(pScrn
);
855 sis310SetCursorAddress(cursor_addr
);
856 if(status1
) sis310SetCursorStatus(status1
)
858 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
859 if(pSiS
->ChipFlags
& SiSCF_CRT2HWCKaputt
) {
860 sis301SetCursorAddress310(cursor_addr2
)
862 if((pSiS
->UseHWARGBCursor
) && (!pSiS
->VBFlags
& DISPTYPE_CRT1
)) {
863 status2
= sis301GetCursorStatus310
;
864 sis301DisableHWCursor310()
865 SISWaitRetraceCRT2(pScrn
);
866 sis301SwitchToMONOCursor310();
868 sis301SetCursorAddress310(cursor_addr
)
869 if(status2
) sis301SetCursorStatus310(status2
)
873 pSiS
->UseHWARGBCursor
= FALSE
;
877 SiSUseHWCursor(ScreenPtr pScreen
, CursorPtr pCurs
)
879 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
880 SISPtr pSiS
= SISPTR(pScrn
);
881 DisplayModePtr mode
= pSiS
->CurrentLayout
.mode
;
883 if(pSiS
->Chipset
!= PCI_CHIP_SIS6326
) return TRUE
;
884 if(!(pSiS
->SiS6326Flags
& SIS6326_TVDETECTED
)) return TRUE
;
885 if((strcmp(mode
->name
, "PAL800x600U") == 0) ||
886 (strcmp(mode
->name
, "NTSC640x480U") == 0))
893 SiS300UseHWCursor(ScreenPtr pScreen
, CursorPtr pCurs
)
895 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
896 SISPtr pSiS
= SISPTR(pScrn
);
897 DisplayModePtr mode
= pSiS
->CurrentLayout
.mode
;
899 DisplayModePtr mode2
= NULL
;
903 mode2
= CDMPTR
->CRT2
;
907 switch (pSiS
->Chipset
) {
908 case PCI_CHIP_SIS300
:
909 case PCI_CHIP_SIS630
:
910 case PCI_CHIP_SIS540
:
911 if(mode
->Flags
& V_INTERLACE
)
913 if((mode
->Flags
& V_DBLSCAN
) && (pCurs
->bits
->height
> 32))
917 if(mode2
->Flags
& V_INTERLACE
)
919 if((mode2
->Flags
& V_DBLSCAN
) && (pCurs
->bits
->height
> 32))
924 case PCI_CHIP_SIS330
:
926 if((!pSiS
->DualHeadMode
) || (!pSiS
->SecondHead
))
928 if(pSiS
->MiscFlags
& MISC_TVNTSC1024
) return FALSE
;
930 case PCI_CHIP_SIS550
:
931 case PCI_CHIP_SIS650
:
932 case PCI_CHIP_SIS315
:
933 case PCI_CHIP_SIS315H
:
934 case PCI_CHIP_SIS315PRO
:
935 case PCI_CHIP_SIS660
:
936 if(mode
->Flags
& V_INTERLACE
)
938 if((mode
->Flags
& V_DBLSCAN
) && (pCurs
->bits
->height
> 32))
942 if(mode2
->Flags
& V_INTERLACE
)
944 if((mode2
->Flags
& V_DBLSCAN
) && (pCurs
->bits
->height
> 32))
950 if(mode
->Flags
& V_INTERLACE
)
952 if((mode
->Flags
& V_DBLSCAN
) && (pCurs
->bits
->height
> 32))
959 #if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0)
961 #ifdef SIS_ARGB_CURSOR
963 SiSUseHWCursorARGB(ScreenPtr pScreen
, CursorPtr pCurs
)
965 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
966 SISPtr pSiS
= SISPTR(pScrn
);
967 DisplayModePtr mode
= pSiS
->CurrentLayout
.mode
;
969 DisplayModePtr mode2
= NULL
;
973 mode2
= CDMPTR
->CRT2
;
977 switch (pSiS
->Chipset
) {
978 case PCI_CHIP_SIS300
:
979 case PCI_CHIP_SIS630
:
980 case PCI_CHIP_SIS540
:
981 if(mode
->Flags
& V_INTERLACE
)
983 if((pCurs
->bits
->height
> 32) || (pCurs
->bits
->width
> 32))
985 if((mode
->Flags
& V_DBLSCAN
) && (pCurs
->bits
->height
> 16))
989 if(mode2
->Flags
& V_INTERLACE
)
991 if((mode2
->Flags
& V_DBLSCAN
) && (pCurs
->bits
->height
> 16))
996 case PCI_CHIP_SIS330
:
998 if((!pSiS
->DualHeadMode
) || (!pSiS
->SecondHead
))
1000 if(pSiS
->MiscFlags
& MISC_TVNTSC1024
) return FALSE
;
1002 case PCI_CHIP_SIS550
:
1003 case PCI_CHIP_SIS650
:
1004 case PCI_CHIP_SIS315
:
1005 case PCI_CHIP_SIS315H
:
1006 case PCI_CHIP_SIS315PRO
:
1007 case PCI_CHIP_SIS660
:
1008 if(mode
->Flags
& V_INTERLACE
)
1010 if((pCurs
->bits
->height
> 64) || (pCurs
->bits
->width
> 64))
1012 if((mode
->Flags
& V_DBLSCAN
) && (pCurs
->bits
->height
> 32))
1014 if((pSiS
->CurrentLayout
.bitsPerPixel
== 8) && (pSiS
->VBFlags
& CRT2_ENABLE
))
1017 if(pSiS
->MergedFB
) {
1018 if(mode2
->Flags
& V_INTERLACE
)
1020 if((mode
->Flags
& V_DBLSCAN
) && (pCurs
->bits
->height
> 32))
1031 static void SiS300LoadCursorImageARGB(ScrnInfoPtr pScrn
, CursorPtr pCurs
)
1033 SISPtr pSiS
= SISPTR(pScrn
);
1034 int cursor_addr
, i
, j
, maxheight
= 32;
1035 CARD32
*src
= pCurs
->bits
->argb
, *p
;
1036 #ifdef SIS300_USE_ARGB16
1039 #define MYSISPTRTYPE CARD16
1042 #define MYSISPTRTYPE CARD32
1044 int srcwidth
= pCurs
->bits
->width
;
1045 int srcheight
= pCurs
->bits
->height
;
1046 CARD32 temp
, status1
= 0, status2
= 0;
1047 BOOLEAN sizedouble
= FALSE
;
1049 SISEntPtr pSiSEnt
= pSiS
->entityPrivate
;
1053 if(pSiS
->MergedFB
) {
1054 if((CDMPTR
->CRT1
->Flags
& V_DBLSCAN
) && (CDMPTR
->CRT2
->Flags
& V_DBLSCAN
)) {
1059 if(pSiS
->CurrentLayout
.mode
->Flags
& V_DBLSCAN
) {
1063 cursor_addr
= pScrn
->videoRam
- pSiS
->cursorOffset
- ((pSiS
->CursorSize
/1024) * 2);
1065 if(srcwidth
> 32) srcwidth
= 32;
1066 if(srcheight
> 32) srcheight
= 32;
1069 if (pSiS
->DualHeadMode
)
1070 /* TW: Use the global (real) FbBase in DHM */
1071 dest
= (MYSISPTRTYPE
*)((unsigned char *)pSiSEnt
->FbBase
+ (cursor_addr
* 1024));
1074 dest
= (MYSISPTRTYPE
*)((unsigned char *)pSiS
->FbBase
+ (cursor_addr
* 1024));
1077 if(srcheight
> 16) srcheight
= 16;
1081 #ifdef SIS300_USE_ARGB16 /* Use 16 Bit RGB pointer */
1082 for(i
= 0; i
< srcheight
; i
++) {
1085 src
+= pCurs
->bits
->width
;
1086 for(j
= 0; j
< srcwidth
; j
++) {
1088 if(temp
& 0xffffff) {
1089 temp1
= ((temp
& 0xff) >> 3) |
1090 ((((temp
& 0xff00) >> (8 + 3)) << 5) & 0x03e0) |
1091 ((((temp
& 0xff0000) >> (16 + 3)) << 10) & 0x7c00);
1092 } else temp1
= 0x8000;
1096 for(; j
< 32; j
++) {
1101 if(srcheight
< maxheight
) {
1102 for(; i
< maxheight
; i
++)
1103 for(j
= 0; j
< 32; j
++) {
1107 for(j
= 0; j
< 32; j
++)
1111 #else /* Use 32bit RGB pointer - preferred, saves us from the conversion */
1112 for(i
= 0; i
< srcheight
; i
++) {
1115 src
+= pCurs
->bits
->width
;
1116 for(j
= 0; j
< srcwidth
; j
++) {
1118 /* *dest1++ = ((temp ^ 0xff000000) << 4) | (((temp ^ 0xff000000) & 0xf0000000) >> 28); */
1119 if(pSiS
->OptUseColorCursorBlend
) {
1120 if(temp
& 0xffffff) {
1121 if((temp
& 0xff000000) > pSiS
->OptColorCursorBlendThreshold
) {
1126 } else temp
= 0xff000000;
1128 if(temp
& 0xffffff) temp
&= 0x00ffffff;
1129 else temp
= 0xff000000;
1134 for(; j
< 32; j
++) {
1135 *dest
++ = 0xff000000;
1139 for(j
= 0; j
< 32; j
++) {
1145 if(srcheight
< maxheight
) {
1146 for(; i
< maxheight
; i
++) {
1147 for(j
= 0; j
< 32; j
++) {
1148 *dest
++ = 0xff000000;
1151 for(j
= 0; j
< 32; j
++) {
1152 *dest
++ = 0xff000000;
1159 if(!pSiS
->UseHWARGBCursor
) {
1160 if(pSiS
->VBFlags
& DISPTYPE_CRT1
) {
1161 status1
= sis300GetCursorStatus
;
1162 sis300DisableHWCursor()
1163 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
1164 status2
= sis301GetCursorStatus
;
1165 sis301DisableHWCursor()
1167 SISWaitRetraceCRT1(pScrn
);
1168 sis300SwitchToRGBCursor();
1169 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
1170 SISWaitRetraceCRT2(pScrn
);
1171 sis301SwitchToRGBCursor();
1176 sis300SetCursorAddress(cursor_addr
);
1177 if(status1
) sis300SetCursorStatus(status1
)
1179 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
1180 if((!pSiS
->UseHWARGBCursor
) && (!pSiS
->VBFlags
& DISPTYPE_CRT1
)) {
1181 status2
= sis301GetCursorStatus
;
1182 sis301DisableHWCursor()
1183 SISWaitRetraceCRT2(pScrn
);
1184 sis301SwitchToRGBCursor();
1186 sis301SetCursorAddress(cursor_addr
)
1187 if(status2
) sis301SetCursorStatus(status2
)
1190 pSiS
->UseHWARGBCursor
= TRUE
;
1193 static void SiS310LoadCursorImageARGB(ScrnInfoPtr pScrn
, CursorPtr pCurs
)
1195 SISPtr pSiS
= SISPTR(pScrn
);
1196 int cursor_addr
, i
, j
, maxheight
= 64;
1197 CARD32
*src
= pCurs
->bits
->argb
, *p
, *pb
, *dest
;
1198 int srcwidth
= pCurs
->bits
->width
;
1199 int srcheight
= pCurs
->bits
->height
;
1200 CARD32 status1
= 0, status2
= 0;
1201 BOOLEAN sizedouble
= FALSE
;
1204 SISEntPtr pSiSEnt
= pSiS
->entityPrivate
;
1208 if(pSiS
->MergedFB
) {
1209 if((CDMPTR
->CRT1
->Flags
& V_DBLSCAN
) && (CDMPTR
->CRT2
->Flags
& V_DBLSCAN
)) {
1214 if(pSiS
->CurrentLayout
.mode
->Flags
& V_DBLSCAN
) {
1219 if(pSiS
->DualHeadMode
) {
1220 pSiSEnt
->HWCursorCBufNum
^= 1;
1221 bufnum
= 1 << pSiSEnt
->HWCursorCBufNum
;
1224 pSiS
->HWCursorCBufNum
^= 1;
1225 bufnum
= 1 << pSiS
->HWCursorCBufNum
;
1230 if(pSiS
->ChipFlags
& SiSCF_CRT2HWCKaputt
) {
1231 cursor_addr
= pScrn
->videoRam
- pSiS
->cursorOffset
- ((pSiS
->CursorSize
/1024) * 2);
1233 cursor_addr
= pScrn
->videoRam
- pSiS
->cursorOffset
- ((pSiS
->CursorSize
/1024) * (2 + bufnum
));
1236 if(srcwidth
> 64) srcwidth
= 64;
1237 if(srcheight
> 64) srcheight
= 64;
1240 if(pSiS
->DualHeadMode
)
1241 /* Use the global (real) FbBase in DHM */
1242 dest
= (CARD32
*)((unsigned char *)pSiSEnt
->FbBase
+ (cursor_addr
* 1024));
1245 dest
= (CARD32
*)((unsigned char *)pSiS
->FbBase
+ (cursor_addr
* 1024));
1248 if(srcheight
> 32) srcheight
= 32;
1252 for(i
= 0; i
< srcheight
; i
++) {
1255 src
+= pCurs
->bits
->width
;
1256 for(j
= 0; j
< srcwidth
; j
++) *dest
++ = *p
++;
1258 for(; j
< 64; j
++) *dest
++ = 0;
1261 for(j
= 0; j
< 64; j
++) {
1266 if(srcheight
< maxheight
) {
1267 for(; i
< maxheight
; i
++) {
1268 for(j
= 0; j
< 64; j
++) *dest
++ = 0;
1270 for(j
= 0; j
< 64; j
++) *dest
++ = 0;
1275 if(pSiS
->ChipFlags
& SiSCF_CRT2HWCKaputt
) {
1277 if(!pSiS
->UseHWARGBCursor
) {
1278 if(pSiS
->VBFlags
& DISPTYPE_CRT1
) {
1279 status1
= sis310GetCursorStatus
;
1280 sis310DisableHWCursor()
1282 SISWaitRetraceCRT1(pScrn
);
1283 sis310SwitchToRGBCursor();
1288 if(!pSiS
->UseHWARGBCursor
) {
1289 if(pSiS
->VBFlags
& DISPTYPE_CRT1
) {
1290 status1
= sis310GetCursorStatus
;
1291 sis310DisableHWCursor()
1292 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
1293 status2
= sis301GetCursorStatus310
;
1294 sis301DisableHWCursor310()
1297 SISWaitRetraceCRT1(pScrn
);
1298 sis310SwitchToRGBCursor();
1299 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
1300 SISWaitRetraceCRT2(pScrn
);
1301 sis301SwitchToRGBCursor310();
1306 sis310SetCursorAddress(cursor_addr
);
1307 if(status1
) sis310SetCursorStatus(status1
)
1309 if(pSiS
->VBFlags
& CRT2_ENABLE
) {
1310 if(pSiS
->ChipFlags
& SiSCF_CRT2HWCKaputt
) {
1311 sis301SetCursorAddress310(cursor_addr
)
1313 if((!pSiS
->UseHWARGBCursor
) && (!pSiS
->VBFlags
& DISPTYPE_CRT1
)) {
1314 status2
= sis301GetCursorStatus310
;
1315 sis301DisableHWCursor310()
1316 SISWaitRetraceCRT2(pScrn
);
1317 sis301SwitchToRGBCursor310();
1319 sis301SetCursorAddress310(cursor_addr
)
1320 if(status2
) sis301SetCursorStatus310(status2
)
1324 pSiS
->UseHWARGBCursor
= TRUE
;
1331 SiSHWCursorInit(ScreenPtr pScreen
)
1333 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
1334 SISPtr pSiS
= SISPTR(pScrn
);
1335 xf86CursorInfoPtr infoPtr
;
1337 infoPtr
= xf86CreateCursorInfoRec();
1338 if(!infoPtr
) return FALSE
;
1340 pSiS
->CursorInfoPtr
= infoPtr
;
1341 pSiS
->UseHWARGBCursor
= FALSE
;
1343 switch (pSiS
->Chipset
) {
1345 case PCI_CHIP_SIS300
:
1346 case PCI_CHIP_SIS630
:
1347 case PCI_CHIP_SIS540
:
1348 infoPtr
->MaxWidth
= 64;
1349 infoPtr
->MaxHeight
= 64;
1350 infoPtr
->ShowCursor
= SiS300ShowCursor
;
1351 infoPtr
->HideCursor
= SiS300HideCursor
;
1352 infoPtr
->SetCursorPosition
= SiS300SetCursorPosition
;
1353 infoPtr
->SetCursorColors
= SiS300SetCursorColors
;
1354 infoPtr
->LoadCursorImage
= SiS300LoadCursorImage
;
1355 infoPtr
->UseHWCursor
= SiS300UseHWCursor
;
1356 #if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0)
1358 #ifdef SIS_ARGB_CURSOR
1359 if(pSiS
->OptUseColorCursor
) {
1360 infoPtr
->UseHWCursorARGB
= SiSUseHWCursorARGB
;
1361 infoPtr
->LoadCursorARGB
= SiS300LoadCursorImageARGB
;
1367 HARDWARE_CURSOR_TRUECOLOR_AT_8BPP
|
1368 HARDWARE_CURSOR_INVERT_MASK
|
1369 HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
|
1370 HARDWARE_CURSOR_AND_SOURCE_WITH_MASK
|
1371 HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK
|
1372 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64
;
1375 case PCI_CHIP_SIS550
:
1376 case PCI_CHIP_SIS650
:
1377 case PCI_CHIP_SIS315
:
1378 case PCI_CHIP_SIS315H
:
1379 case PCI_CHIP_SIS315PRO
:
1380 case PCI_CHIP_SIS330
:
1381 case PCI_CHIP_SIS660
:
1382 infoPtr
->MaxWidth
= 64;
1383 infoPtr
->MaxHeight
= 64;
1384 infoPtr
->ShowCursor
= SiS310ShowCursor
;
1385 infoPtr
->HideCursor
= SiS310HideCursor
;
1386 infoPtr
->SetCursorPosition
= SiS310SetCursorPosition
;
1387 infoPtr
->SetCursorColors
= SiS310SetCursorColors
;
1388 infoPtr
->LoadCursorImage
= SiS310LoadCursorImage
;
1389 infoPtr
->UseHWCursor
= SiS300UseHWCursor
;
1390 #if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,99,0,0)
1392 #ifdef SIS_ARGB_CURSOR
1393 if(pSiS
->OptUseColorCursor
) {
1394 infoPtr
->UseHWCursorARGB
= SiSUseHWCursorARGB
;
1395 infoPtr
->LoadCursorARGB
= SiS310LoadCursorImageARGB
;
1401 HARDWARE_CURSOR_TRUECOLOR_AT_8BPP
|
1402 HARDWARE_CURSOR_INVERT_MASK
|
1403 HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
|
1404 HARDWARE_CURSOR_AND_SOURCE_WITH_MASK
|
1405 HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK
|
1406 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64
;
1410 infoPtr
->MaxWidth
= 64;
1411 infoPtr
->MaxHeight
= 64;
1412 infoPtr
->SetCursorPosition
= SiSSetCursorPosition
;
1413 infoPtr
->ShowCursor
= SiSShowCursor
;
1414 infoPtr
->HideCursor
= SiSHideCursor
;
1415 infoPtr
->SetCursorColors
= SiSSetCursorColors
;
1416 infoPtr
->LoadCursorImage
= SiSLoadCursorImage
;
1417 infoPtr
->UseHWCursor
= SiSUseHWCursor
;
1419 HARDWARE_CURSOR_TRUECOLOR_AT_8BPP
|
1420 HARDWARE_CURSOR_INVERT_MASK
|
1421 HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
|
1422 HARDWARE_CURSOR_AND_SOURCE_WITH_MASK
|
1423 HARDWARE_CURSOR_NIBBLE_SWAPPED
|
1424 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1
;
1428 return(xf86InitCursor(pScreen
, infoPtr
));