1/*
2 * Copyright © 2006 Keith Packard
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission.  The copyright holders make no representations
11 * about the suitability of this software for any purpose.  It is provided "as
12 * is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 * OF THIS SOFTWARE.
21 */
22
23#ifdef HAVE_XORG_CONFIG_H
24#include <xorg-config.h>
25#endif
26
27#include "xf86.h"
28#include "xf86DDC.h"
29#include "xf86_OSproc.h"
30#include "dgaproc.h"
31#include "xf86Crtc.h"
32#include "xf86Modes.h"
33#include "gcstruct.h"
34#include "scrnintstr.h"
35#include "windowstr.h"
36
37static Bool
38xf86_dga_get_modes(ScreenPtr pScreen)
39{
40    ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
41    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
42    DGAModePtr modes, mode;
43    DisplayModePtr display_mode;
44    int bpp = scrn->bitsPerPixel >> 3;
45    int num;
46
47    num = 0;
48    display_mode = scrn->modes;
49    while (display_mode) {
50        num++;
51        display_mode = display_mode->next;
52        if (display_mode == scrn->modes)
53            break;
54    }
55
56    if (!num)
57        return FALSE;
58
59    modes = xallocarray(num, sizeof(DGAModeRec));
60    if (!modes)
61        return FALSE;
62
63    num = 0;
64    display_mode = scrn->modes;
65    while (display_mode) {
66        mode = modes + num++;
67
68        mode->mode = display_mode;
69        mode->flags = DGA_CONCURRENT_ACCESS;
70        if (display_mode->Flags & V_DBLSCAN)
71            mode->flags |= DGA_DOUBLESCAN;
72        if (display_mode->Flags & V_INTERLACE)
73            mode->flags |= DGA_INTERLACED;
74        mode->byteOrder = scrn->imageByteOrder;
75        mode->depth = scrn->depth;
76        mode->bitsPerPixel = scrn->bitsPerPixel;
77        mode->red_mask = scrn->mask.red;
78        mode->green_mask = scrn->mask.green;
79        mode->blue_mask = scrn->mask.blue;
80        mode->visualClass = (bpp == 1) ? PseudoColor : TrueColor;
81        mode->viewportWidth = display_mode->HDisplay;
82        mode->viewportHeight = display_mode->VDisplay;
83        mode->xViewportStep = (bpp == 3) ? 2 : 1;
84        mode->yViewportStep = 1;
85        mode->viewportFlags = DGA_FLIP_RETRACE;
86        mode->offset = 0;
87        mode->address = 0;
88        mode->imageWidth = mode->viewportWidth;
89        mode->imageHeight = mode->viewportHeight;
90        mode->bytesPerScanline = (mode->imageWidth * scrn->bitsPerPixel) >> 3;
91        mode->pixmapWidth = mode->imageWidth;
92        mode->pixmapHeight = mode->imageHeight;
93        mode->maxViewportX = 0;
94        mode->maxViewportY = 0;
95
96        display_mode = display_mode->next;
97        if (display_mode == scrn->modes)
98            break;
99    }
100    free(xf86_config->dga_modes);
101    xf86_config->dga_nmode = num;
102    xf86_config->dga_modes = modes;
103    return TRUE;
104}
105
106static Bool
107xf86_dga_set_mode(ScrnInfoPtr scrn, DGAModePtr display_mode)
108{
109    ScreenPtr pScreen = scrn->pScreen;
110    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
111
112    if (!display_mode) {
113        if (xf86_config->dga_save_mode) {
114            xf86SwitchMode(pScreen, xf86_config->dga_save_mode);
115            xf86_config->dga_save_mode = NULL;
116        }
117    }
118    else {
119        if (!xf86_config->dga_save_mode) {
120            xf86_config->dga_save_mode = scrn->currentMode;
121            xf86SwitchMode(pScreen, display_mode->mode);
122        }
123    }
124    return TRUE;
125}
126
127static int
128xf86_dga_get_viewport(ScrnInfoPtr scrn)
129{
130    return 0;
131}
132
133static void
134xf86_dga_set_viewport(ScrnInfoPtr scrn, int x, int y, int flags)
135{
136    scrn->AdjustFrame(scrn, x, y);
137}
138
139static Bool
140xf86_dga_open_framebuffer(ScrnInfoPtr scrn,
141                          char **name,
142                          unsigned char **mem, int *size, int *offset,
143                          int *flags)
144{
145    return FALSE;
146}
147
148static void
149xf86_dga_close_framebuffer(ScrnInfoPtr scrn)
150{
151}
152
153static DGAFunctionRec xf86_dga_funcs = {
154    xf86_dga_open_framebuffer,
155    xf86_dga_close_framebuffer,
156    xf86_dga_set_mode,
157    xf86_dga_set_viewport,
158    xf86_dga_get_viewport,
159    NULL,
160    NULL,
161    NULL,
162    NULL
163};
164
165Bool
166xf86DiDGAReInit(ScreenPtr pScreen)
167{
168    return TRUE;
169}
170
171Bool
172_xf86_di_dga_reinit_internal(ScreenPtr pScreen)
173{
174    ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
175    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
176
177    if (!DGAScreenAvailable(pScreen))
178        return TRUE;
179
180    if (!xf86_dga_get_modes(pScreen))
181        return FALSE;
182
183    return DGAReInitModes(pScreen, xf86_config->dga_modes,
184                          xf86_config->dga_nmode);
185}
186
187Bool
188xf86DiDGAInit(ScreenPtr pScreen, unsigned long dga_address)
189{
190    return TRUE;
191}
192
193Bool
194_xf86_di_dga_init_internal(ScreenPtr pScreen)
195{
196    ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
197    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
198
199    xf86_config->dga_flags = 0;
200    xf86_config->dga_address = 0;
201    xf86_config->dga_width = 0;
202    xf86_config->dga_height = 0;
203    xf86_config->dga_stride = 0;
204
205    if (!xf86_dga_get_modes(pScreen))
206        return FALSE;
207
208    return DGAInit(pScreen, &xf86_dga_funcs, xf86_config->dga_modes,
209                   xf86_config->dga_nmode);
210}
211