xpra icon
Bug tracker and wiki

This bug tracker and wiki are being discontinued
please use https://github.com/Xpra-org/xpra instead.


Ticket #349: dummy_driver.c

File dummy_driver.c, 25.8 KB (added by Antoine Martin, 7 years ago)

hacked dummy driver with the geometry fix

Line 
1
2/*
3 * Copyright 2002, SuSE Linux AG, Author: Egbert Eich
4 */
5
6#ifdef HAVE_CONFIG_H
7#include "config.h"
8#endif
9
10/* All drivers should typically include these */
11#include "xf86.h"
12#include "xf86_OSproc.h"
13
14/* All drivers initialising the SW cursor need this */
15#include "mipointer.h"
16
17/* All drivers using the mi colormap manipulation need this */
18#include "micmap.h"
19
20#ifdef RANDR
21#include "randrstr.h"
22#endif
23
24#include "windowstr.h"
25
26/* identifying atom needed by magnifiers */
27#include <X11/Xatom.h>
28#include "property.h"
29
30#include "xf86cmap.h"
31
32#include "xf86fbman.h"
33
34#include "fb.h"
35
36#include "picturestr.h"
37
38#ifdef XvExtension
39#include "xf86xv.h"
40#include <X11/extensions/Xv.h>
41#endif
42
43
44/*
45 * Driver data structures.
46 */
47#include "dummy.h"
48
49/* These need to be checked */
50#include <X11/X.h>
51#include <X11/Xproto.h>
52#include "scrnintstr.h"
53#include "servermd.h"
54#ifdef USE_DGA
55#define _XF86DGA_SERVER_
56#include <X11/extensions/xf86dgaproto.h>
57#endif
58
59#include <xf86Crtc.h>
60#include "inputstr.h"
61
62/* Mandatory functions */
63static const OptionInfoRec *    DUMMYAvailableOptions(int chipid, int busid);
64static void     DUMMYIdentify(int flags);
65static Bool     DUMMYProbe(DriverPtr drv, int flags);
66static Bool     DUMMYPreInit(ScrnInfoPtr pScrn, int flags);
67static Bool     DUMMYScreenInit(SCREEN_INIT_ARGS_DECL);
68static Bool     DUMMYEnterVT(VT_FUNC_ARGS_DECL);
69static void     DUMMYLeaveVT(VT_FUNC_ARGS_DECL);
70static Bool     DUMMYCloseScreen(CLOSE_SCREEN_ARGS_DECL);
71static Bool     DUMMYCreateWindow(WindowPtr pWin);
72static void     DUMMYFreeScreen(FREE_SCREEN_ARGS_DECL);
73static ModeStatus DUMMYValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode,
74                                 Bool verbose, int flags);
75static Bool     DUMMYSaveScreen(ScreenPtr pScreen, int mode);
76
77/* Internally used functions */
78static Bool     dummyModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
79static void     dummySave(ScrnInfoPtr pScrn);
80static void     dummyRestore(ScrnInfoPtr pScrn, Bool restoreText);
81static Bool     dummyDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op,
82                                pointer ptr);
83
84
85/* static void     DUMMYDisplayPowerManagementSet(ScrnInfoPtr pScrn, */
86/*                              int PowerManagementMode, int flags); */
87
88#define DUMMY_VERSION 4000
89#define DUMMY_NAME "DUMMY"
90#define DUMMY_DRIVER_NAME "dummy"
91
92#define DUMMY_MAJOR_VERSION PACKAGE_VERSION_MAJOR
93#define DUMMY_MINOR_VERSION PACKAGE_VERSION_MINOR
94#define DUMMY_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL
95
96#define DUMMY_MAX_WIDTH 32767
97#define DUMMY_MAX_HEIGHT 32767
98
99/*
100 * This is intentionally screen-independent.  It indicates the binding
101 * choice made in the first PreInit.
102 */
103static int pix24bpp = 0;
104
105
106/*
107 * This contains the functions needed by the server after loading the driver
108 * module.  It must be supplied, and gets passed back by the SetupProc
109 * function in the dynamic case.  In the static case, a reference to this
110 * is compiled in, and this requires that the name of this DriverRec be
111 * an upper-case version of the driver name.
112 */
113
114_X_EXPORT DriverRec DUMMY = {
115    DUMMY_VERSION,
116    DUMMY_DRIVER_NAME,
117    DUMMYIdentify,
118    DUMMYProbe,
119    DUMMYAvailableOptions,
120    NULL,
121    0,
122    dummyDriverFunc
123};
124
125static SymTabRec DUMMYChipsets[] = {
126    { DUMMY_CHIP,   "dummy" },
127    { -1,                NULL }
128};
129
130typedef enum {
131    OPTION_SW_CURSOR,
132    OPTION_CONSTANT_DPI
133} DUMMYOpts;
134
135static const OptionInfoRec DUMMYOptions[] = {
136    { OPTION_SW_CURSOR, "SWcursor",     OPTV_BOOLEAN,   {0}, FALSE },
137#ifdef RANDR
138    { OPTION_CONSTANT_DPI,      "ConstantDPI",  OPTV_BOOLEAN,   {0}, FALSE },
139#endif
140    { -1,                  NULL,           OPTV_NONE,   {0}, FALSE }
141};
142
143#ifdef XFree86LOADER
144
145static MODULESETUPPROTO(dummySetup);
146
147static XF86ModuleVersionInfo dummyVersRec =
148{
149        "dummy",
150        MODULEVENDORSTRING,
151        MODINFOSTRING1,
152        MODINFOSTRING2,
153        XORG_VERSION_CURRENT,
154        DUMMY_MAJOR_VERSION, DUMMY_MINOR_VERSION, DUMMY_PATCHLEVEL,
155        ABI_CLASS_VIDEODRV,
156        ABI_VIDEODRV_VERSION,
157        MOD_CLASS_VIDEODRV,
158        {0,0,0,0}
159};
160
161/*
162 * This is the module init data.
163 * Its name has to be the driver name followed by ModuleData
164 */
165_X_EXPORT XF86ModuleData dummyModuleData = { &dummyVersRec, dummySetup, NULL };
166
167static pointer
168dummySetup(pointer module, pointer opts, int *errmaj, int *errmin)
169{
170    static Bool setupDone = FALSE;
171
172    if (!setupDone) {
173        setupDone = TRUE;
174        xf86AddDriver(&DUMMY, module, HaveDriverFuncs);
175
176        /*
177         * Modules that this driver always requires can be loaded here
178         * by calling LoadSubModule().
179         */
180
181        /*
182         * The return value must be non-NULL on success even though there
183         * is no TearDownProc.
184         */
185        return (pointer)1;
186    } else {
187        if (errmaj) *errmaj = LDR_ONCEONLY;
188        return NULL;
189    }
190}
191
192#endif /* XFree86LOADER */
193
194static Bool
195DUMMYGetRec(ScrnInfoPtr pScrn)
196{
197    /*
198     * Allocate a DUMMYRec, and hook it into pScrn->driverPrivate.
199     * pScrn->driverPrivate is initialised to NULL, so we can check if
200     * the allocation has already been done.
201     */
202    if (pScrn->driverPrivate != NULL)
203        return TRUE;
204
205    pScrn->driverPrivate = xnfcalloc(sizeof(DUMMYRec), 1);
206
207    if (pScrn->driverPrivate == NULL)
208        return FALSE;
209        return TRUE;
210}
211
212static void
213DUMMYFreeRec(ScrnInfoPtr pScrn)
214{
215    if (pScrn->driverPrivate == NULL)
216        return;
217    free(pScrn->driverPrivate);
218    pScrn->driverPrivate = NULL;
219}
220
221static const OptionInfoRec *
222DUMMYAvailableOptions(int chipid, int busid)
223{
224    return DUMMYOptions;
225}
226
227/* Mandatory */
228static void
229DUMMYIdentify(int flags)
230{
231    xf86PrintChipsets(DUMMY_NAME, "Driver for Dummy chipsets",
232                        DUMMYChipsets);
233}
234
235/* Mandatory */
236static Bool
237DUMMYProbe(DriverPtr drv, int flags)
238{
239    Bool foundScreen = FALSE;
240    int numDevSections, numUsed;
241    GDevPtr *devSections;
242    int i;
243
244    if (flags & PROBE_DETECT)
245        return FALSE;
246    /*
247     * Find the config file Device sections that match this
248     * driver, and return if there are none.
249     */
250    if ((numDevSections = xf86MatchDevice(DUMMY_DRIVER_NAME,
251                                          &devSections)) <= 0) {
252        return FALSE;
253    }
254
255    numUsed = numDevSections;
256
257    if (numUsed > 0) {
258
259        for (i = 0; i < numUsed; i++) {
260            ScrnInfoPtr pScrn = NULL;
261            int entityIndex = 
262                xf86ClaimNoSlot(drv,DUMMY_CHIP,devSections[i],TRUE);
263            /* Allocate a ScrnInfoRec and claim the slot */
264            if ((pScrn = xf86AllocateScreen(drv,0 ))) {
265                   xf86AddEntityToScreen(pScrn,entityIndex);
266                    pScrn->driverVersion = DUMMY_VERSION;
267                    pScrn->driverName    = DUMMY_DRIVER_NAME;
268                    pScrn->name          = DUMMY_NAME;
269                    pScrn->Probe         = DUMMYProbe;
270                    pScrn->PreInit       = DUMMYPreInit;
271                    pScrn->ScreenInit    = DUMMYScreenInit;
272                    pScrn->SwitchMode    = DUMMYSwitchMode;
273                    pScrn->AdjustFrame   = DUMMYAdjustFrame;
274                    pScrn->EnterVT       = DUMMYEnterVT;
275                    pScrn->LeaveVT       = DUMMYLeaveVT;
276                    pScrn->FreeScreen    = DUMMYFreeScreen;
277                    pScrn->ValidMode     = DUMMYValidMode;
278
279                    foundScreen = TRUE;
280            }
281        }
282    }   
283    return foundScreen;
284}
285
286# define RETURN \
287    { DUMMYFreeRec(pScrn);\
288                            return FALSE;\
289                                             }
290
291/* Mandatory */
292Bool
293DUMMYPreInit(ScrnInfoPtr pScrn, int flags)
294{
295    ClockRangePtr clockRanges;
296    int i;
297    DUMMYPtr dPtr;
298    int maxClock = 230000;
299    GDevPtr device = xf86GetEntityInfo(pScrn->entityList[0])->device;
300
301    if (flags & PROBE_DETECT) 
302        return TRUE;
303   
304    /* Allocate the DummyRec driverPrivate */
305    if (!DUMMYGetRec(pScrn)) {
306        return FALSE;
307    }
308   
309    dPtr = DUMMYPTR(pScrn);
310
311    pScrn->chipset = (char *)xf86TokenToString(DUMMYChipsets,
312                                               DUMMY_CHIP);
313
314    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Chipset is a DUMMY\n");
315   
316    pScrn->monitor = pScrn->confScreen->monitor;
317
318    if (!xf86SetDepthBpp(pScrn, 0, 0, 0,  Support24bppFb | Support32bppFb))
319        return FALSE;
320    else {
321        /* Check that the returned depth is one we support */
322        switch (pScrn->depth) {
323        case 8:
324        case 15:
325        case 16:
326        case 24:
327            break;
328        default:
329            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
330                       "Given depth (%d) is not supported by this driver\n",
331                       pScrn->depth);
332            return FALSE;
333        }
334    }
335
336    xf86PrintDepthBpp(pScrn);
337    if (pScrn->depth == 8)
338        pScrn->rgbBits = 8;
339
340    /* Get the depth24 pixmap format */
341    if (pScrn->depth == 24 && pix24bpp == 0)
342        pix24bpp = xf86GetBppFromDepth(pScrn, 24);
343
344    /*
345     * This must happen after pScrn->display has been set because
346     * xf86SetWeight references it.
347     */
348    if (pScrn->depth > 8) {
349        /* The defaults are OK for us */
350        rgb zeros = {0, 0, 0};
351
352        if (!xf86SetWeight(pScrn, zeros, zeros)) {
353            return FALSE;
354        } else {
355            /* XXX check that weight returned is supported */
356            ;
357        }
358    }
359
360    if (!xf86SetDefaultVisual(pScrn, -1)) 
361        return FALSE;
362
363    if (pScrn->depth > 1) {
364        Gamma zeros = {0.0, 0.0, 0.0};
365
366        if (!xf86SetGamma(pScrn, zeros))
367            return FALSE;
368    }
369
370    xf86CollectOptions(pScrn, device->options);
371    /* Process the options */
372    if (!(dPtr->Options = malloc(sizeof(DUMMYOptions))))
373        return FALSE;
374    memcpy(dPtr->Options, DUMMYOptions, sizeof(DUMMYOptions));
375
376    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, dPtr->Options);
377
378    xf86GetOptValBool(dPtr->Options, OPTION_SW_CURSOR,&dPtr->swCursor);
379    xf86GetOptValBool(dPtr->Options, OPTION_CONSTANT_DPI, &dPtr->constantDPI);
380
381    if (device->videoRam != 0) {
382        pScrn->videoRam = device->videoRam;
383        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VideoRAM: %d kByte\n",
384                   pScrn->videoRam);
385    } else {
386        pScrn->videoRam = 4096;
387        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kByte\n",
388                   pScrn->videoRam);
389    }
390   
391    if (device->dacSpeeds[0] != 0) {
392        maxClock = device->dacSpeeds[0];
393        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Max Clock: %d kHz\n",
394                   maxClock);
395    } else {
396        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Max Clock: %d kHz\n",
397                   maxClock);
398    }
399
400    pScrn->progClock = TRUE;
401    /*
402     * Setup the ClockRanges, which describe what clock ranges are available,
403     * and what sort of modes they can be used for.
404     */
405    clockRanges = (ClockRangePtr)xnfcalloc(sizeof(ClockRange), 1);
406    clockRanges->next = NULL;
407    clockRanges->ClockMulFactor = 1;
408    clockRanges->minClock = 11000;   /* guessed §§§ */
409    clockRanges->maxClock = 300000;
410    clockRanges->clockIndex = -1;               /* programmable */
411    clockRanges->interlaceAllowed = TRUE; 
412    clockRanges->doubleScanAllowed = TRUE;
413
414    /* Subtract memory for HW cursor */
415
416
417    {
418        int apertureSize = (pScrn->videoRam * 1024);
419        i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
420                              pScrn->display->modes, clockRanges,
421                              NULL, 256, DUMMY_MAX_WIDTH,
422                              (8 * pScrn->bitsPerPixel),
423                              128, DUMMY_MAX_HEIGHT, pScrn->display->virtualX,
424                              pScrn->display->virtualY, apertureSize,
425                              LOOKUP_BEST_REFRESH);
426
427       if (i == -1)
428           RETURN;
429    }
430
431    /* Prune the modes marked as invalid */
432    xf86PruneDriverModes(pScrn);
433
434    if (i == 0 || pScrn->modes == NULL) {
435        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
436        RETURN;
437    }
438
439    /*
440     * Set the CRTC parameters for all of the modes based on the type
441     * of mode, and the chipset's interlace requirements.
442     *
443     * Calling this is required if the mode->Crtc* values are used by the
444     * driver and if the driver doesn't provide code to set them.  They
445     * are not pre-initialised at all.
446     */
447    xf86SetCrtcForModes(pScrn, 0); 
448 
449    /* Set the current mode to the first in the list */
450    pScrn->currentMode = pScrn->modes;
451
452    /* Print the list of modes being used */
453    xf86PrintModes(pScrn);
454
455    /* If monitor resolution is set on the command line, use it */
456    xf86SetDpi(pScrn, 0, 0);
457
458    if (xf86LoadSubModule(pScrn, "fb") == NULL) {
459        RETURN;
460    }
461
462    if (!dPtr->swCursor) {
463        if (!xf86LoadSubModule(pScrn, "ramdac"))
464            RETURN;
465    }
466   
467    /* We have no contiguous physical fb in physical memory */
468    pScrn->memPhysBase = 0;
469    pScrn->fbOffset = 0;
470
471    return TRUE;
472}
473#undef RETURN
474
475/* Mandatory */
476static Bool
477DUMMYEnterVT(VT_FUNC_ARGS_DECL)
478{
479    SCRN_INFO_PTR(arg);
480   
481    /* Should we re-save the text mode on each VT enter? */
482    if(!dummyModeInit(pScrn, pScrn->currentMode))
483      return FALSE;
484
485    DUMMYAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
486
487    return TRUE;
488}
489
490/* Mandatory */
491static void
492DUMMYLeaveVT(VT_FUNC_ARGS_DECL)
493{
494    SCRN_INFO_PTR(arg);
495    dummyRestore(pScrn, TRUE);
496}
497
498static void
499DUMMYLoadPalette(
500   ScrnInfoPtr pScrn,
501   int numColors,
502   int *indices,
503   LOCO *colors,
504   VisualPtr pVisual
505){
506   int i, index, shift, Gshift;
507   DUMMYPtr dPtr = DUMMYPTR(pScrn);
508
509   switch(pScrn->depth) {
510   case 15:     
511        shift = Gshift = 1;
512        break;
513   case 16:
514        shift = 0; 
515        Gshift = 0;
516        break;
517   default:
518        shift = Gshift = 0;
519        break;
520   }
521
522   for(i = 0; i < numColors; i++) {
523       index = indices[i];
524       dPtr->colors[index].red = colors[index].red << shift;
525       dPtr->colors[index].green = colors[index].green << Gshift;
526       dPtr->colors[index].blue = colors[index].blue << shift;
527   } 
528
529}
530
531static ScrnInfoPtr DUMMYScrn; /* static-globalize it */
532
533/* Mandatory */
534static Bool
535DUMMYScreenInit(SCREEN_INIT_ARGS_DECL)
536{
537    ScrnInfoPtr pScrn;
538    DUMMYPtr dPtr;
539    int ret;
540    VisualPtr visual;
541   
542    /*
543     * we need to get the ScrnInfoRec for this screen, so let's allocate
544     * one first thing
545     */
546    pScrn = xf86ScreenToScrn(pScreen);
547    dPtr = DUMMYPTR(pScrn);
548    DUMMYScrn = pScrn;
549
550
551    if (!(dPtr->FBBase = malloc(pScrn->videoRam * 1024)))
552        return FALSE;
553   
554    /*
555     * next we save the current state and setup the first mode
556     */
557    dummySave(pScrn);
558   
559    if (!dummyModeInit(pScrn,pScrn->currentMode))
560        return FALSE;
561    DUMMYAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
562
563    /*
564     * Reset visual list.
565     */
566    miClearVisualTypes();
567   
568    /* Setup the visuals we support. */
569   
570    if (!miSetVisualTypes(pScrn->depth,
571                      miGetDefaultVisualMask(pScrn->depth),
572                      pScrn->rgbBits, pScrn->defaultVisual))
573         return FALSE;
574
575    if (!miSetPixmapDepths ()) return FALSE;
576
577    /*
578     * Call the framebuffer layer's ScreenInit function, and fill in other
579     * pScreen fields.
580     */
581    ret = fbScreenInit(pScreen, dPtr->FBBase,
582                            pScrn->virtualX, pScrn->virtualY,
583                            pScrn->xDpi, pScrn->yDpi,
584                            pScrn->displayWidth, pScrn->bitsPerPixel);
585    if (!ret)
586        return FALSE;
587
588    if (pScrn->depth > 8) {
589        /* Fixup RGB ordering */
590        visual = pScreen->visuals + pScreen->numVisuals;
591        while (--visual >= pScreen->visuals) {
592            if ((visual->class | DynamicClass) == DirectColor) {
593                visual->offsetRed = pScrn->offset.red;
594                visual->offsetGreen = pScrn->offset.green;
595                visual->offsetBlue = pScrn->offset.blue;
596                visual->redMask = pScrn->mask.red;
597                visual->greenMask = pScrn->mask.green;
598                visual->blueMask = pScrn->mask.blue;
599            }
600        }
601    }
602   
603    /* must be after RGB ordering fixed */
604    fbPictureInit(pScreen, 0, 0);
605
606    xf86SetBlackWhitePixels(pScreen);
607
608#ifdef USE_DGA
609    DUMMYDGAInit(pScreen);
610#endif
611   
612    if (dPtr->swCursor)
613        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using Software Cursor.\n");
614
615    {
616
617         
618        BoxRec AvailFBArea;
619        int lines = pScrn->videoRam * 1024 /
620            (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3));
621        AvailFBArea.x1 = 0;
622        AvailFBArea.y1 = 0;
623        AvailFBArea.x2 = pScrn->displayWidth;
624        AvailFBArea.y2 = lines;
625        xf86InitFBManager(pScreen, &AvailFBArea); 
626       
627        xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
628                   "Using %i scanlines of offscreen memory \n"
629                   , lines - pScrn->virtualY);
630    }
631
632    xf86SetBackingStore(pScreen);
633    xf86SetSilkenMouse(pScreen);
634
635    //pScreen->isGPU = 0;
636       
637    /* Initialise cursor functions */
638    miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
639
640
641    if (!dPtr->swCursor) {
642      /* HW cursor functions */
643      if (!DUMMYCursorInit(pScreen)) {
644          xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
645                     "Hardware cursor initialization failed\n");
646          return FALSE;
647      }
648    }
649   
650    /* Initialise default colourmap */
651    if(!miCreateDefColormap(pScreen))
652        return FALSE;
653
654    if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits,
655                         DUMMYLoadPalette, NULL, 
656                         CMAP_PALETTED_TRUECOLOR
657                             | CMAP_RELOAD_ON_MODE_SWITCH))
658        return FALSE;
659
660/*     DUMMYInitVideo(pScreen); */
661
662    pScreen->SaveScreen = DUMMYSaveScreen;
663
664   
665    /* Wrap the current CloseScreen function */
666    dPtr->CloseScreen = pScreen->CloseScreen;
667    pScreen->CloseScreen = DUMMYCloseScreen;
668
669    /* Wrap the current CreateWindow function */
670    dPtr->CreateWindow = pScreen->CreateWindow;
671    pScreen->CreateWindow = DUMMYCreateWindow;
672
673    pScreen->ConstrainCursorHarder = NULL;
674
675    /* Report any unused options (only for the first generation) */
676    if (serverGeneration == 1) {
677        xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
678    }
679
680    return TRUE;
681}
682
683const char *XDPY_PROPERTY = "dummy-constant-xdpi";
684const char *YDPY_PROPERTY = "dummy-constant-ydpi";
685static int get_dpi_value(WindowPtr root, const char *property_name, int default_dpi)
686{
687    PropertyPtr prop;
688    Atom type_atom = MakeAtom("CARDINAL", 8, TRUE);
689    Atom prop_atom = MakeAtom(property_name, strlen(property_name), FALSE);
690
691    for (prop = wUserProps(root); prop; prop = prop->next) {
692       if (prop->propertyName == prop_atom && prop->type == type_atom && prop->data) {
693           int v = (int) (*((CARD32 *) prop->data));
694           if ((v>0) && (v<4096)) {
695               xf86DrvMsg(0, X_INFO, "get_constant_dpi_value() found property \"%s\" with value=%i\n", property_name, (int) v);
696               return (int) v;
697           }
698           break;
699       }
700    }
701    return default_dpi;
702}
703
704/* Mandatory */
705Bool
706DUMMYSwitchMode(SWITCH_MODE_ARGS_DECL)
707{
708    SCRN_INFO_PTR(arg);
709    if (!dummyModeInit(pScrn, mode))
710        return FALSE;
711    pScrn->pScreen->ConstrainCursorHarder = NULL;
712#ifdef RANDR
713    DUMMYPtr dPtr = DUMMYPTR(pScrn);
714    if (dPtr->constantDPI) {
715        int xDpi = get_dpi_value(pScrn->pScreen->root, XDPY_PROPERTY, pScrn->xDpi);
716        int yDpi = get_dpi_value(pScrn->pScreen->root, YDPY_PROPERTY, pScrn->yDpi);
717        //25.4 mm per inch: (254/10)
718        pScrn->pScreen->mmWidth = mode->HDisplay * 254 / xDpi / 10;
719        pScrn->pScreen->mmHeight = mode->VDisplay * 254 / yDpi / 10;
720        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "mm(dpi %ix%i)=%ix%i\n", xDpi, yDpi, pScrn->pScreen->mmWidth, pScrn->pScreen->mmHeight);
721        RRScreenSizeNotify(pScrn->pScreen);
722        RRTellChanged(pScrn->pScreen);
723    }
724#endif
725    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Screen: %ix%i\n", pScrn->pScreen->width, pScrn->pScreen->height);
726    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " frame: %i,%i,%i,%i\n", pScrn->frameX0, pScrn->frameY0, pScrn->frameX1, pScrn->frameY1);
727    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " virtual: %ix%i\n", pScrn->virtualX, pScrn->virtualY);
728    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " mode: %ix%i\n", mode->HDisplay, mode->VDisplay); 
729    pScrn->pScreen->width = mode->HDisplay;
730    pScrn->pScreen->height = mode->VDisplay;
731    pScrn->virtualX = mode->HDisplay;
732    pScrn->virtualY = mode->VDisplay;
733    pScrn->frameX1 = mode->HDisplay;
734    pScrn->frameY1 = mode->VDisplay;
735    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Screen: %ix%i\n", pScrn->pScreen->width, pScrn->pScreen->height);
736    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " frame: %i,%i,%i,%i\n", pScrn->frameX0, pScrn->frameY0, pScrn->frameX1, pScrn->frameY1);
737    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " virtual: %ix%i\n", pScrn->virtualX, pScrn->virtualY);
738    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " mode: %ix%i\n", mode->HDisplay, mode->VDisplay); 
739    //xf86SetCrtcForModes(pScrn, 0);
740    //xf86SetModeCrtc(pScrn->modes, 0);
741    //xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Modes: %s : %ix%i\n", pScrn->modes->name, pScrn->modes->HTotal, pScrn->modes->VTotal);
742    int c,d;
743 
744    rrScrPrivPtr rrScrPriv = rrGetScrPriv(pScrn->pScreen);
745    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "rrScrPriv: %p\n", rrScrPriv);
746    for (c = 0; c < rrScrPriv->numCrtcs; c++) {
747        RRCrtcPtr crtc = rrScrPriv->crtcs[c];
748        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "crtc[%i]: %p %i outputs\n", c, &crtc, crtc->numOutputs);
749        //xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "crtc[%i]: %p\n", c, &crtc);
750        for (d = 0; d < crtc->numOutputs; d++) {
751            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " output[%i] = %s", d, crtc->outputs[d]->name);
752        }
753        xf86CrtcPtr xfcrtc = crtc->devPrivate;
754        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "CRTC: %i: %p\n", c, xfcrtc);
755    }
756
757    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "InputInfo: %p\n", &inputInfo);
758    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "InputInfo.devices: %p\n", inputInfo.devices);
759    DeviceIntPtr pDev;
760    SpritePtr pSprite;
761    WindowPtr pWin;
762    c = 0;
763    for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
764    {
765        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "device=%p\n", pDev);
766        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " enabled=%i\n", pDev->enabled);
767        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " coreEvents=%i\n", pDev->coreEvents);
768        if (pDev->config_info!=NULL)
769            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " config_info=%p\n", pDev->config_info);
770        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " spriteInfo=%p\n", pDev->spriteInfo);
771        if (pDev->spriteInfo)
772        {
773            pSprite = pDev->spriteInfo->sprite;
774            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " confined=%i\n", pSprite->confined);
775            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " pSprite[%d]=%p\n", c, pSprite);
776            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " hotLimits=%i,%i,%i,%i\n", pSprite->hotLimits.x1, pSprite->hotLimits.y1, pSprite->hotLimits.x2, pSprite->hotLimits.y2);
777            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " physLimits=%i,%i,%i,%i\n", pSprite->physLimits.x1, pSprite->physLimits.y1, pSprite->physLimits.x2, pSprite->physLimits.y2);
778            pWin = pSprite->confineWin;
779            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " confineWin=%p\n", pWin);
780            if (pWin!=NULL) {
781            }
782            pSprite->hotLimits.x2 = mode->HDisplay;
783            pSprite->hotLimits.y2 = mode->VDisplay;
784            pSprite->physLimits.x2 = mode->HDisplay;
785            pSprite->physLimits.y2 = mode->VDisplay;
786        }
787        c++;
788    }
789
790
791    //RRCrtcPtr rrcrtc = xf86GetPrimaryCrtc(pScrn->pScreen)->randr_crtc;
792    //xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "crtc: %p\n", rrcrtc);
793    //rrcrtc = xf86CompatRRCrtc(pScrn);
794    //xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "crtc: %p\n", rrcrtc);
795
796    //xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
797    //xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "config: %p\n", config);
798    //lazy: just update all the crtcs!
799    /*for (c = 0; c < config->num_crtc; c++) {
800        xf86CrtcPtr crtc = config->crtc[c];
801        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "CRTC: %i: %p\n", c, crtc);
802        if (crtc!=NULL) {
803            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "CRTC: %i: active=%i\n", c, crtc->active);
804            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, " bounds: %i,%i,%i,%i", crtc->bounds.x1, crtc->bounds.y1, crtc->bounds.x2, crtc->bounds.y2);
805        }
806        //crtc->bounds = NULL;
807    }*/
808    //BarrierScreenPtr cs = GetBarrierScreen(screen);
809    //XIBarrierInit()
810    //XIBarrierReset();
811    //XFixesDestroyPointerBarrier();
812    //BarrierScreenPtr cs = GetBarrierScreen(pScreen);
813    //XFixesDestroyPointerBarrier(Display *dpy, PointerBarrier b);
814    //xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Screen: %ix%i\n", pScrn->displayWidth, pScrn->displayHeight);
815
816    return TRUE;
817}
818
819/* Mandatory */
820void
821DUMMYAdjustFrame(ADJUST_FRAME_ARGS_DECL)
822{
823    SCRN_INFO_PTR(arg);
824    int Base; 
825
826    Base = (y * pScrn->displayWidth + x) >> 2;
827
828    /* Scale Base by the number of bytes per pixel. */
829    switch (pScrn->depth) {
830    case  8 :
831        break;
832    case 15 :
833    case 16 :
834        Base *= 2;
835        break;
836    case 24 :
837        Base *= 3;
838        break;
839    default :
840        break;
841    }
842}
843
844/* Mandatory */
845static Bool
846DUMMYCloseScreen(CLOSE_SCREEN_ARGS_DECL)
847{
848    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
849    DUMMYPtr dPtr = DUMMYPTR(pScrn);
850
851    if(pScrn->vtSema){
852        dummyRestore(pScrn, TRUE);
853        free(dPtr->FBBase);
854    }
855
856    if (dPtr->CursorInfo)
857        xf86DestroyCursorInfoRec(dPtr->CursorInfo);
858
859    pScrn->vtSema = FALSE;
860    pScreen->CloseScreen = dPtr->CloseScreen;
861    return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
862}
863
864/* Optional */
865static void
866DUMMYFreeScreen(FREE_SCREEN_ARGS_DECL)
867{
868    SCRN_INFO_PTR(arg);
869    DUMMYFreeRec(pScrn);
870}
871
872static Bool
873DUMMYSaveScreen(ScreenPtr pScreen, int mode)
874{
875    ScrnInfoPtr pScrn = NULL;
876    DUMMYPtr dPtr;
877
878    if (pScreen != NULL) {
879        pScrn = xf86ScreenToScrn(pScreen);
880        dPtr = DUMMYPTR(pScrn);
881
882        dPtr->screenSaver = xf86IsUnblank(mode);
883    } 
884    return TRUE;
885}
886
887/* Optional */
888static ModeStatus
889DUMMYValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags)
890{
891    return(MODE_OK);
892}
893
894static void
895dummySave(ScrnInfoPtr pScrn)
896{
897}
898
899static void 
900dummyRestore(ScrnInfoPtr pScrn, Bool restoreText)
901{
902}
903   
904static Bool
905dummyModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
906{
907    dummyRestore(pScrn, FALSE);
908   
909    return(TRUE);
910}
911
912Atom VFB_PROP  = 0;
913#define  VFB_PROP_NAME  "VFB_IDENT"
914
915static Bool
916DUMMYCreateWindow(WindowPtr pWin)
917{
918    ScreenPtr pScreen = pWin->drawable.pScreen;
919    DUMMYPtr dPtr = DUMMYPTR(DUMMYScrn);
920    WindowPtr pWinRoot;
921    int ret;
922
923    pScreen->CreateWindow = dPtr->CreateWindow;
924    ret = pScreen->CreateWindow(pWin);
925    dPtr->CreateWindow = pScreen->CreateWindow;
926    pScreen->CreateWindow = DUMMYCreateWindow;
927
928    if(ret != TRUE)
929        return(ret);
930       
931    if(dPtr->prop == FALSE) {
932#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 8
933        pWinRoot = WindowTable[DUMMYScrn->pScreen->myNum];
934#else
935        pWinRoot = DUMMYScrn->pScreen->root;
936#endif
937        if (! ValidAtom(VFB_PROP))
938            VFB_PROP = MakeAtom(VFB_PROP_NAME, strlen(VFB_PROP_NAME), 1);
939
940        ret = ChangeWindowProperty(pWinRoot, VFB_PROP, XA_STRING, 
941                8, PropModeReplace, (int)4, (pointer)"TRUE", FALSE);
942        if( ret != Success)
943                ErrorF("Could not set VFB root window property");
944        dPtr->prop = TRUE;
945
946        return TRUE;
947    }
948    return TRUE;
949}
950
951#ifndef HW_SKIP_CONSOLE
952#define HW_SKIP_CONSOLE 4
953#endif
954
955static Bool
956dummyDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr)
957{
958    CARD32 *flag;
959   
960    switch (op) {
961        case GET_REQUIRED_HW_INTERFACES:
962            flag = (CARD32*)ptr;
963            (*flag) = HW_SKIP_CONSOLE;
964            return TRUE;
965        default:
966            return FALSE;
967    }
968}