1706f2543Smrg/*
2706f2543Smrg * Copyright © 2004 Keith Packard
3706f2543Smrg *
4706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its
5706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that
6706f2543Smrg * the above copyright notice appear in all copies and that both that
7706f2543Smrg * copyright notice and this permission notice appear in supporting
8706f2543Smrg * documentation, and that the name of Keith Packard not be used in
9706f2543Smrg * advertising or publicity pertaining to distribution of the software without
10706f2543Smrg * specific, written prior permission.  Keith Packard makes no
11706f2543Smrg * representations about the suitability of this software for any purpose.  It
12706f2543Smrg * is provided "as is" without express or implied warranty.
13706f2543Smrg *
14706f2543Smrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16706f2543Smrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20706f2543Smrg * PERFORMANCE OF THIS SOFTWARE.
21706f2543Smrg */
22706f2543Smrg
23706f2543Smrg#ifdef HAVE_CONFIG_H
24706f2543Smrg#include <kdrive-config.h>
25706f2543Smrg#endif
26706f2543Smrg#include "fake.h"
27706f2543Smrg
28706f2543Smrgextern int KdTsPhyScreen;
29706f2543Smrg
30706f2543SmrgBool
31706f2543SmrgfakeInitialize (KdCardInfo *card, FakePriv *priv)
32706f2543Smrg{
33706f2543Smrg    priv->base = 0;
34706f2543Smrg    priv->bytes_per_line = 0;
35706f2543Smrg    return TRUE;
36706f2543Smrg}
37706f2543Smrg
38706f2543SmrgBool
39706f2543SmrgfakeCardInit (KdCardInfo *card)
40706f2543Smrg{
41706f2543Smrg    FakePriv	*priv;
42706f2543Smrg
43706f2543Smrg    priv = (FakePriv *) malloc(sizeof (FakePriv));
44706f2543Smrg    if (!priv)
45706f2543Smrg	return FALSE;
46706f2543Smrg
47706f2543Smrg    if (!fakeInitialize (card, priv))
48706f2543Smrg    {
49706f2543Smrg	free(priv);
50706f2543Smrg	return FALSE;
51706f2543Smrg    }
52706f2543Smrg    card->driver = priv;
53706f2543Smrg
54706f2543Smrg    return TRUE;
55706f2543Smrg}
56706f2543Smrg
57706f2543SmrgBool
58706f2543SmrgfakeScreenInitialize (KdScreenInfo *screen, FakeScrPriv *scrpriv)
59706f2543Smrg{
60706f2543Smrg    if (!screen->width || !screen->height)
61706f2543Smrg    {
62706f2543Smrg	screen->width = 1024;
63706f2543Smrg	screen->height = 768;
64706f2543Smrg	screen->rate = 72;
65706f2543Smrg    }
66706f2543Smrg
67706f2543Smrg    if (screen->width <= 0)
68706f2543Smrg	screen->width = 1;
69706f2543Smrg    if (screen->height <= 0)
70706f2543Smrg	screen->height = 1;
71706f2543Smrg
72706f2543Smrg    if (!screen->fb.depth)
73706f2543Smrg	screen->fb.depth = 16;
74706f2543Smrg
75706f2543Smrg    if (screen->fb.depth <= 8)
76706f2543Smrg    {
77706f2543Smrg	screen->fb.visuals = ((1 << StaticGray) |
78706f2543Smrg			      (1 << GrayScale) |
79706f2543Smrg			      (1 << StaticColor) |
80706f2543Smrg			      (1 << PseudoColor) |
81706f2543Smrg			      (1 << TrueColor) |
82706f2543Smrg			      (1 << DirectColor));
83706f2543Smrg    }
84706f2543Smrg    else
85706f2543Smrg    {
86706f2543Smrg	screen->fb.visuals = (1 << TrueColor);
87706f2543Smrg#define Mask(o,l)   (((1 << l) - 1) << o)
88706f2543Smrg	if (screen->fb.depth <= 15)
89706f2543Smrg	{
90706f2543Smrg	    screen->fb.depth = 15;
91706f2543Smrg	    screen->fb.bitsPerPixel = 16;
92706f2543Smrg	    screen->fb.redMask = Mask (10, 5);
93706f2543Smrg	    screen->fb.greenMask = Mask (5, 5);
94706f2543Smrg	    screen->fb.blueMask = Mask (0, 5);
95706f2543Smrg	}
96706f2543Smrg	else if (screen->fb.depth <= 16)
97706f2543Smrg	{
98706f2543Smrg	    screen->fb.depth = 16;
99706f2543Smrg	    screen->fb.bitsPerPixel = 16;
100706f2543Smrg	    screen->fb.redMask = Mask (11, 5);
101706f2543Smrg	    screen->fb.greenMask = Mask (5, 6);
102706f2543Smrg	    screen->fb.blueMask = Mask (0, 5);
103706f2543Smrg	}
104706f2543Smrg	else
105706f2543Smrg	{
106706f2543Smrg	    screen->fb.depth = 24;
107706f2543Smrg	    screen->fb.bitsPerPixel = 32;
108706f2543Smrg	    screen->fb.redMask = Mask (16, 8);
109706f2543Smrg	    screen->fb.greenMask = Mask (8, 8);
110706f2543Smrg	    screen->fb.blueMask = Mask (0, 8);
111706f2543Smrg	}
112706f2543Smrg    }
113706f2543Smrg
114706f2543Smrg    scrpriv->randr = screen->randr;
115706f2543Smrg
116706f2543Smrg    return fakeMapFramebuffer (screen);
117706f2543Smrg}
118706f2543Smrg
119706f2543SmrgBool
120706f2543SmrgfakeScreenInit (KdScreenInfo *screen)
121706f2543Smrg{
122706f2543Smrg    FakeScrPriv *scrpriv;
123706f2543Smrg
124706f2543Smrg    scrpriv = calloc(1, sizeof (FakeScrPriv));
125706f2543Smrg    if (!scrpriv)
126706f2543Smrg	return FALSE;
127706f2543Smrg    screen->driver = scrpriv;
128706f2543Smrg    if (!fakeScreenInitialize (screen, scrpriv))
129706f2543Smrg    {
130706f2543Smrg	screen->driver = 0;
131706f2543Smrg	free(scrpriv);
132706f2543Smrg	return FALSE;
133706f2543Smrg    }
134706f2543Smrg    return TRUE;
135706f2543Smrg}
136706f2543Smrg
137706f2543Smrgvoid *
138706f2543SmrgfakeWindowLinear (ScreenPtr	pScreen,
139706f2543Smrg		   CARD32	row,
140706f2543Smrg		   CARD32	offset,
141706f2543Smrg		   int		mode,
142706f2543Smrg		   CARD32	*size,
143706f2543Smrg		   void		*closure)
144706f2543Smrg{
145706f2543Smrg    KdScreenPriv(pScreen);
146706f2543Smrg    FakePriv	    *priv = pScreenPriv->card->driver;
147706f2543Smrg
148706f2543Smrg    if (!pScreenPriv->enabled)
149706f2543Smrg	return 0;
150706f2543Smrg    *size = priv->bytes_per_line;
151706f2543Smrg    return priv->base + row * priv->bytes_per_line;
152706f2543Smrg}
153706f2543Smrg
154706f2543SmrgBool
155706f2543SmrgfakeMapFramebuffer (KdScreenInfo *screen)
156706f2543Smrg{
157706f2543Smrg    FakeScrPriv	*scrpriv = screen->driver;
158706f2543Smrg    KdPointerMatrix	m;
159706f2543Smrg    FakePriv		*priv = screen->card->driver;
160706f2543Smrg
161706f2543Smrg    if (scrpriv->randr != RR_Rotate_0)
162706f2543Smrg	scrpriv->shadow = TRUE;
163706f2543Smrg    else
164706f2543Smrg	scrpriv->shadow = FALSE;
165706f2543Smrg
166706f2543Smrg    KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height);
167706f2543Smrg
168706f2543Smrg    KdSetPointerMatrix (&m);
169706f2543Smrg
170706f2543Smrg    priv->bytes_per_line = ((screen->width * screen->fb.bitsPerPixel + 31) >> 5) << 2;
171706f2543Smrg    free(priv->base);
172706f2543Smrg    priv->base = malloc (priv->bytes_per_line * screen->height);
173706f2543Smrg
174706f2543Smrg    if (scrpriv->shadow)
175706f2543Smrg    {
176706f2543Smrg	if (!KdShadowFbAlloc (screen, scrpriv->randr & (RR_Rotate_90|RR_Rotate_270)))
177706f2543Smrg	    return FALSE;
178706f2543Smrg    }
179706f2543Smrg    else
180706f2543Smrg    {
181706f2543Smrg        screen->fb.byteStride = priv->bytes_per_line;
182706f2543Smrg        screen->fb.pixelStride = (priv->bytes_per_line * 8/
183706f2543Smrg				     screen->fb.bitsPerPixel);
184706f2543Smrg        screen->fb.frameBuffer = (CARD8 *) (priv->base);
185706f2543Smrg    }
186706f2543Smrg
187706f2543Smrg    return TRUE;
188706f2543Smrg}
189706f2543Smrg
190706f2543Smrgvoid
191706f2543SmrgfakeSetScreenSizes (ScreenPtr pScreen)
192706f2543Smrg{
193706f2543Smrg    KdScreenPriv(pScreen);
194706f2543Smrg    KdScreenInfo	*screen = pScreenPriv->screen;
195706f2543Smrg    FakeScrPriv	*scrpriv = screen->driver;
196706f2543Smrg
197706f2543Smrg    if (scrpriv->randr & (RR_Rotate_0|RR_Rotate_180))
198706f2543Smrg    {
199706f2543Smrg	pScreen->width = screen->width;
200706f2543Smrg	pScreen->height = screen->height;
201706f2543Smrg	pScreen->mmWidth = screen->width_mm;
202706f2543Smrg	pScreen->mmHeight = screen->height_mm;
203706f2543Smrg    }
204706f2543Smrg    else
205706f2543Smrg    {
206706f2543Smrg	pScreen->width = screen->width;
207706f2543Smrg	pScreen->height = screen->height;
208706f2543Smrg	pScreen->mmWidth = screen->height_mm;
209706f2543Smrg	pScreen->mmHeight = screen->width_mm;
210706f2543Smrg    }
211706f2543Smrg}
212706f2543Smrg
213706f2543SmrgBool
214706f2543SmrgfakeUnmapFramebuffer (KdScreenInfo *screen)
215706f2543Smrg{
216706f2543Smrg    FakePriv		*priv = screen->card->driver;
217706f2543Smrg    KdShadowFbFree (screen);
218706f2543Smrg    free(priv->base);
219706f2543Smrg    priv->base = NULL;
220706f2543Smrg    return TRUE;
221706f2543Smrg}
222706f2543Smrg
223706f2543SmrgBool
224706f2543SmrgfakeSetShadow (ScreenPtr pScreen)
225706f2543Smrg{
226706f2543Smrg    KdScreenPriv(pScreen);
227706f2543Smrg    KdScreenInfo	*screen = pScreenPriv->screen;
228706f2543Smrg    FakeScrPriv	*scrpriv = screen->driver;
229706f2543Smrg    ShadowUpdateProc	update;
230706f2543Smrg    ShadowWindowProc	window;
231706f2543Smrg
232706f2543Smrg    window = fakeWindowLinear;
233706f2543Smrg    update = 0;
234706f2543Smrg    if (scrpriv->randr)
235706f2543Smrg	update = shadowUpdateRotatePacked;
236706f2543Smrg    else
237706f2543Smrg	update = shadowUpdatePacked;
238706f2543Smrg    return KdShadowSet (pScreen, scrpriv->randr, update, window);
239706f2543Smrg}
240706f2543Smrg
241706f2543Smrg
242706f2543Smrg#ifdef RANDR
243706f2543SmrgBool
244706f2543SmrgfakeRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
245706f2543Smrg{
246706f2543Smrg    KdScreenPriv(pScreen);
247706f2543Smrg    KdScreenInfo	    *screen = pScreenPriv->screen;
248706f2543Smrg    FakeScrPriv	    *scrpriv = screen->driver;
249706f2543Smrg    RRScreenSizePtr	    pSize;
250706f2543Smrg    Rotation		    randr;
251706f2543Smrg    int			    n;
252706f2543Smrg
253706f2543Smrg    *rotations = RR_Rotate_All|RR_Reflect_All;
254706f2543Smrg
255706f2543Smrg    for (n = 0; n < pScreen->numDepths; n++)
256706f2543Smrg	if (pScreen->allowedDepths[n].numVids)
257706f2543Smrg	    break;
258706f2543Smrg    if (n == pScreen->numDepths)
259706f2543Smrg	return FALSE;
260706f2543Smrg
261706f2543Smrg    pSize = RRRegisterSize (pScreen,
262706f2543Smrg			    screen->width,
263706f2543Smrg			    screen->height,
264706f2543Smrg			    screen->width_mm,
265706f2543Smrg			    screen->height_mm);
266706f2543Smrg
267706f2543Smrg    randr = KdSubRotation (scrpriv->randr, screen->randr);
268706f2543Smrg
269706f2543Smrg    RRSetCurrentConfig (pScreen, randr, 0, pSize);
270706f2543Smrg
271706f2543Smrg    return TRUE;
272706f2543Smrg}
273706f2543Smrg
274706f2543SmrgBool
275706f2543SmrgfakeRandRSetConfig (ScreenPtr		pScreen,
276706f2543Smrg		     Rotation		randr,
277706f2543Smrg		     int		rate,
278706f2543Smrg		     RRScreenSizePtr	pSize)
279706f2543Smrg{
280706f2543Smrg    KdScreenPriv(pScreen);
281706f2543Smrg    KdScreenInfo	*screen = pScreenPriv->screen;
282706f2543Smrg    FakeScrPriv	*scrpriv = screen->driver;
283706f2543Smrg    Bool		wasEnabled = pScreenPriv->enabled;
284706f2543Smrg    FakeScrPriv	oldscr;
285706f2543Smrg    int			oldwidth;
286706f2543Smrg    int			oldheight;
287706f2543Smrg    int			oldmmwidth;
288706f2543Smrg    int			oldmmheight;
289706f2543Smrg    int			newwidth, newheight;
290706f2543Smrg
291706f2543Smrg    if (screen->randr & (RR_Rotate_0|RR_Rotate_180))
292706f2543Smrg    {
293706f2543Smrg	newwidth = pSize->width;
294706f2543Smrg	newheight = pSize->height;
295706f2543Smrg    }
296706f2543Smrg    else
297706f2543Smrg    {
298706f2543Smrg	newwidth = pSize->height;
299706f2543Smrg	newheight = pSize->width;
300706f2543Smrg    }
301706f2543Smrg
302706f2543Smrg    if (wasEnabled)
303706f2543Smrg	KdDisableScreen (pScreen);
304706f2543Smrg
305706f2543Smrg    oldscr = *scrpriv;
306706f2543Smrg
307706f2543Smrg    oldwidth = screen->width;
308706f2543Smrg    oldheight = screen->height;
309706f2543Smrg    oldmmwidth = pScreen->mmWidth;
310706f2543Smrg    oldmmheight = pScreen->mmHeight;
311706f2543Smrg
312706f2543Smrg    /*
313706f2543Smrg     * Set new configuration
314706f2543Smrg     */
315706f2543Smrg
316706f2543Smrg    scrpriv->randr = KdAddRotation (screen->randr, randr);
317706f2543Smrg
318706f2543Smrg    fakeUnmapFramebuffer (screen);
319706f2543Smrg
320706f2543Smrg    if (!fakeMapFramebuffer (screen))
321706f2543Smrg	goto bail4;
322706f2543Smrg
323706f2543Smrg    KdShadowUnset (screen->pScreen);
324706f2543Smrg
325706f2543Smrg    if (!fakeSetShadow (screen->pScreen))
326706f2543Smrg	goto bail4;
327706f2543Smrg
328706f2543Smrg    fakeSetScreenSizes (screen->pScreen);
329706f2543Smrg
330706f2543Smrg    /*
331706f2543Smrg     * Set frame buffer mapping
332706f2543Smrg     */
333706f2543Smrg    (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
334706f2543Smrg				    pScreen->width,
335706f2543Smrg				    pScreen->height,
336706f2543Smrg				    screen->fb.depth,
337706f2543Smrg				    screen->fb.bitsPerPixel,
338706f2543Smrg				    screen->fb.byteStride,
339706f2543Smrg				    screen->fb.frameBuffer);
340706f2543Smrg
341706f2543Smrg    /* set the subpixel order */
342706f2543Smrg
343706f2543Smrg    KdSetSubpixelOrder (pScreen, scrpriv->randr);
344706f2543Smrg    if (wasEnabled)
345706f2543Smrg	KdEnableScreen (pScreen);
346706f2543Smrg
347706f2543Smrg    return TRUE;
348706f2543Smrg
349706f2543Smrgbail4:
350706f2543Smrg    fakeUnmapFramebuffer (screen);
351706f2543Smrg    *scrpriv = oldscr;
352706f2543Smrg    (void) fakeMapFramebuffer (screen);
353706f2543Smrg    pScreen->width = oldwidth;
354706f2543Smrg    pScreen->height = oldheight;
355706f2543Smrg    pScreen->mmWidth = oldmmwidth;
356706f2543Smrg    pScreen->mmHeight = oldmmheight;
357706f2543Smrg
358706f2543Smrg    if (wasEnabled)
359706f2543Smrg	KdEnableScreen (pScreen);
360706f2543Smrg    return FALSE;
361706f2543Smrg}
362706f2543Smrg
363706f2543SmrgBool
364706f2543SmrgfakeRandRInit (ScreenPtr pScreen)
365706f2543Smrg{
366706f2543Smrg    rrScrPrivPtr    pScrPriv;
367706f2543Smrg
368706f2543Smrg    if (!RRScreenInit (pScreen))
369706f2543Smrg	return FALSE;
370706f2543Smrg
371706f2543Smrg    pScrPriv = rrGetScrPriv(pScreen);
372706f2543Smrg    pScrPriv->rrGetInfo = fakeRandRGetInfo;
373706f2543Smrg    pScrPriv->rrSetConfig = fakeRandRSetConfig;
374706f2543Smrg    return TRUE;
375706f2543Smrg}
376706f2543Smrg#endif
377706f2543Smrg
378706f2543SmrgBool
379706f2543SmrgfakeCreateColormap (ColormapPtr pmap)
380706f2543Smrg{
381706f2543Smrg    return fbInitializeColormap (pmap);
382706f2543Smrg}
383706f2543Smrg
384706f2543SmrgBool
385706f2543SmrgfakeInitScreen (ScreenPtr pScreen)
386706f2543Smrg{
387706f2543Smrg#ifdef TOUCHSCREEN
388706f2543Smrg    KdTsPhyScreen = pScreen->myNum;
389706f2543Smrg#endif
390706f2543Smrg
391706f2543Smrg    pScreen->CreateColormap = fakeCreateColormap;
392706f2543Smrg    return TRUE;
393706f2543Smrg}
394706f2543Smrg
395706f2543SmrgBool
396706f2543SmrgfakeFinishInitScreen (ScreenPtr pScreen)
397706f2543Smrg{
398706f2543Smrg    if (!shadowSetup (pScreen))
399706f2543Smrg	return FALSE;
400706f2543Smrg
401706f2543Smrg#ifdef RANDR
402706f2543Smrg    if (!fakeRandRInit (pScreen))
403706f2543Smrg	return FALSE;
404706f2543Smrg#endif
405706f2543Smrg
406706f2543Smrg    return TRUE;
407706f2543Smrg}
408706f2543Smrg
409706f2543Smrg
410706f2543SmrgBool
411706f2543SmrgfakeCreateResources (ScreenPtr pScreen)
412706f2543Smrg{
413706f2543Smrg    return fakeSetShadow (pScreen);
414706f2543Smrg}
415706f2543Smrg
416706f2543Smrgvoid
417706f2543SmrgfakePreserve (KdCardInfo *card)
418706f2543Smrg{
419706f2543Smrg}
420706f2543Smrg
421706f2543SmrgBool
422706f2543SmrgfakeEnable (ScreenPtr pScreen)
423706f2543Smrg{
424706f2543Smrg    return TRUE;
425706f2543Smrg}
426706f2543Smrg
427706f2543SmrgBool
428706f2543SmrgfakeDPMS (ScreenPtr pScreen, int mode)
429706f2543Smrg{
430706f2543Smrg    return TRUE;
431706f2543Smrg}
432706f2543Smrg
433706f2543Smrgvoid
434706f2543SmrgfakeDisable (ScreenPtr pScreen)
435706f2543Smrg{
436706f2543Smrg}
437706f2543Smrg
438706f2543Smrgvoid
439706f2543SmrgfakeRestore (KdCardInfo *card)
440706f2543Smrg{
441706f2543Smrg}
442706f2543Smrg
443706f2543Smrgvoid
444706f2543SmrgfakeScreenFini (KdScreenInfo *screen)
445706f2543Smrg{
446706f2543Smrg}
447706f2543Smrg
448706f2543Smrgvoid
449706f2543SmrgfakeCardFini (KdCardInfo *card)
450706f2543Smrg{
451706f2543Smrg    FakePriv	*priv = card->driver;
452706f2543Smrg
453706f2543Smrg    free (priv->base);
454706f2543Smrg    free(priv);
455706f2543Smrg}
456706f2543Smrg
457706f2543Smrgvoid
458706f2543SmrgfakeGetColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
459706f2543Smrg{
460706f2543Smrg    while (n--)
461706f2543Smrg    {
462706f2543Smrg	pdefs->red = 0;
463706f2543Smrg	pdefs->green = 0;
464706f2543Smrg	pdefs->blue = 0;
465706f2543Smrg	pdefs++;
466706f2543Smrg    }
467706f2543Smrg}
468706f2543Smrg
469706f2543Smrgvoid
470706f2543SmrgfakePutColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
471706f2543Smrg{
472706f2543Smrg}
473