tga_cursor.c revision 7706df26
1/*
2 * Copyright 1999 by Matthew Grossman, Seattle, USA.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software
5 * and its documentation for any purpose is hereby granted without
6 * fee, provided that the above copyright notice appear in all copies
7 * and that both that copyright notice and this permission notice
8 * appear in supporting documentation, and that the name of Matthew
9 * Grossman not be used in advertising or publicity pertaining to
10 * distribution of the software without specific, written prior
11 * permission.  Matthew Grossman makes no representations about the
12 * suitability of this software for any purpose.  It is provided "as
13 * is" without express or implied warranty.
14 *
15 * MATTHEW GROSSMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
16 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 * FITNESS, IN NO EVENT SHALL MATTHEW GROSSMAN BE LIABLE FOR ANY
18 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
20 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
21 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
22 * SOFTWARE.
23 *
24 * Author:  Matthew Grossman, mattg@oz.net
25 *
26 * DEC TGA hardware cursor using BT485 ramdac
27 */
28/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_cursor.c,v 1.1 1999/04/17 07:06:58 dawes Exp $ */
29
30#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
34/* tga_cursor.c */
35
36#include "xf86.h"
37#include "xf86PciInfo.h"
38#include "xf86Pci.h"
39#include "BT.h"
40
41#include "tga.h"
42#include "tga_regs.h"
43
44/* defines */
45/* BT485 also supports 32 bit cursor, but why use it? */
46#define CURSOR_SIZE 64
47
48/* protos */
49
50static void TGALoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
51static void TGAShowCursor(ScrnInfoPtr pScrn);
52static void TGAHideCursor(ScrnInfoPtr pScrn);
53static void TGASetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
54static void TGASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
55
56static void
57TGALoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
58{
59  TGAPtr pTga = TGAPTR(pScrn);
60  int i;
61
62  /* set 64 bit cursor */
63  pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_0, 0x7F, 0x80);
64  pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0x00, 0x01);
65  pTga->RamDacRec->WriteDAC(pScrn, BT_STATUS_REG, 0xF8, 0x04);
66
67  /* first write address reg @ 0x0, then write 0xb with the data (for 32 bit
68     cursor) */
69
70  pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0xFC, 0x00);
71
72  for(i = 0; i < ((CURSOR_SIZE * CURSOR_SIZE) / 8); i++)
73    pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_RAM_DATA, 0x00, *src++);
74
75  for(i = 0; i < ((CURSOR_SIZE * CURSOR_SIZE) / 8); i++)
76    pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_RAM_DATA, 0x00, *src++);
77
78/*    pTga->RamDacRec->WriteDAC(pScrn, BT_WRITE_ADDR, 0xFC, 0x00); */
79
80  return;
81}
82
83
84static void
85TGAShowCursor(ScrnInfoPtr pScrn)
86{
87  TGAPtr pTga = TGAPTR(pScrn);
88
89  /* enable BT485 X11 cursor */
90  pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_2, 0xFC, 0x03);
91
92  return;
93}
94
95
96static void
97TGAHideCursor(ScrnInfoPtr pScrn)
98{
99  TGAPtr pTga = TGAPTR(pScrn);
100
101  pTga->RamDacRec->WriteDAC(pScrn, BT_COMMAND_REG_2, 0xFC, 0x00);
102
103  return;
104}
105
106static void
107TGASetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
108{
109   TGAPtr pTga = TGAPTR(pScrn);
110   unsigned int tmp_x, tmp_y;
111
112   /* translate x && y to BT485 cursor addresses */
113
114   tmp_x = x + CURSOR_SIZE;
115   tmp_x &= 0x0FFF;
116
117   tmp_y = y + CURSOR_SIZE;
118   tmp_y &= 0x0FFF;
119
120   /* write out the addresses */
121   pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_X_LOW, 0x00, (tmp_x & 0xFF));
122   pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_X_HIGH, 0xF0, (tmp_x >> 8));
123
124   pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_Y_LOW, 0x00, (tmp_y & 0xFF));
125   pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_Y_HIGH, 0xF0, (tmp_y >> 8));
126
127   return;
128}
129
130
131static void
132TGASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
133     /* set pScrn->cursor_fg and pScrn->cursor_bg */
134{
135  TGAPtr pTga = TGAPTR(pScrn);
136
137    /* first, load address register at 0x4 with 0x1, then write 3 color
138       octets RGB to 0x5 (background), then write three octets to 0x5
139       (foreground), then write to address register 0xFC */
140
141  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_WR_ADDR, 0xFC, 0x01);
142
143  /* we don't seem to support the 6 bit DAC option as of 4.0, and why
144     would we? */
145  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (bg & 0x00FF0000) >> 16);
146  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (bg & 0x0000FF00) >> 8);
147  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (bg & 0x000000FF));
148
149  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (fg & 0x00FF0000) >> 16);
150  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (fg & 0x0000FF00) >> 8);
151  pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_DATA, 0x00, (fg & 0x000000FF));
152
153/*    pTga->RamDacRec->WriteDAC(pScrn, BT_CURS_WR_ADDR, 0xFC, 0x00); */
154
155  return;
156}
157
158
159Bool
160TGAHWCursorInit(ScreenPtr pScreen)
161{
162    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
163    TGAPtr pTga;
164    xf86CursorInfoPtr infoPtr;
165
166    pTga = TGAPTR(pScrn);
167
168    infoPtr = xf86CreateCursorInfoRec();
169    if(!infoPtr) return FALSE;
170
171    pTga->CursorInfoRec = infoPtr;
172
173    infoPtr->MaxWidth = CURSOR_SIZE;
174    infoPtr->MaxHeight = CURSOR_SIZE;
175    infoPtr->Flags =  HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
176      HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
177      HARDWARE_CURSOR_TRUECOLOR_AT_8BPP;
178
179    infoPtr->SetCursorColors = TGASetCursorColors;
180    infoPtr->SetCursorPosition = TGASetCursorPosition;
181    infoPtr->LoadCursorImage = TGALoadCursorImage;
182    infoPtr->HideCursor = TGAHideCursor;
183    infoPtr->ShowCursor = TGAShowCursor;
184    infoPtr->UseHWCursor = NULL;
185
186    return(xf86InitCursor(pScreen, infoPtr));
187}
188
189