3 Copyright 1993, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included
12 in all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 OTHER DEALINGS IN THE SOFTWARE.
22 Except as contained in this notice, the name of The Open Group shall
23 not be used in advertising or otherwise to promote the sale, use or
24 other dealings in this Software without prior written authorization
29 #include <dix-config.h>
32 #include <X11/Xwinsock.h>
36 #include <X11/Xproto.h>
39 #include "dix/colormap_priv.h"
40 #include "dix/dix_priv.h"
41 #include "dix/screenint_priv.h"
42 #include "os/cmdline.h"
43 #include "os/ddx_priv.h"
46 #include "scrnintstr.h"
50 #include "colormapst.h"
53 #include "mipointer.h"
55 #include <sys/types.h>
61 #endif /* HAVE_MMAP */
65 #include <sys/param.h>
67 #include <X11/XWDFile.h>
74 #include "glx_extinit.h"
77 #define VFB_DEFAULT_WIDTH 1280
78 #define VFB_DEFAULT_HEIGHT 1024
79 #define VFB_DEFAULT_DEPTH 24
80 #define VFB_DEFAULT_WHITEPIXEL 1
81 #define VFB_DEFAULT_BLACKPIXEL 0
82 #define VFB_DEFAULT_LINEBIAS 0
83 #define XWD_WINDOW_NAME_LEN 60
96 XWDFileHeader
*pXWDHeader
;
99 unsigned int lineBias
;
100 CloseScreenProcPtr closeScreen
;
104 char mmap_file
[MAXPATHLEN
];
110 } vfbScreenInfo
, *vfbScreenInfoPtr
;
112 static int vfbNumScreens
;
113 static vfbScreenInfo
*vfbScreens
;
115 static vfbScreenInfo defaultScreenInfo
= {
116 .width
= VFB_DEFAULT_WIDTH
,
117 .height
= VFB_DEFAULT_HEIGHT
,
118 .depth
= VFB_DEFAULT_DEPTH
,
119 .blackPixel
= VFB_DEFAULT_BLACKPIXEL
,
120 .whitePixel
= VFB_DEFAULT_WHITEPIXEL
,
121 .lineBias
= VFB_DEFAULT_LINEBIAS
,
124 static Bool vfbPixmapDepths
[33];
127 static char *pfbdir
= NULL
;
129 typedef enum { NORMAL_MEMORY_FB
, SHARED_MEMORY_FB
, MMAPPED_FILE_FB
} fbMemType
;
130 static fbMemType fbmemtype
= NORMAL_MEMORY_FB
;
131 static char needswap
= 0;
132 static Bool Render
= TRUE
;
134 #define swapcopy16(_dst, _src) \
135 if (needswap) { CARD16 _s = _src; cpswaps(_s, _dst); } \
138 #define swapcopy32(_dst, _src) \
139 if (needswap) { CARD32 _s = _src; cpswapl(_s, _dst); } \
143 vfbInitializePixmapDepths(void)
147 vfbPixmapDepths
[1] = TRUE
; /* always need bitmaps */
148 for (i
= 2; i
<= 32; i
++)
149 vfbPixmapDepths
[i
] = FALSE
;
153 vfbBitsPerPixel(int depth
)
159 else if (depth
<= 16)
166 freeScreenInfo(vfbScreenInfoPtr pvfb
)
170 case MMAPPED_FILE_FB
:
171 if (-1 == unlink(pvfb
->mmap_file
)) {
173 ErrorF("unlink %s failed, %s",
174 pvfb
->mmap_file
, strerror(errno
));
177 #else /* HAVE_MMAP */
178 case MMAPPED_FILE_FB
:
180 #endif /* HAVE_MMAP */
183 case SHARED_MEMORY_FB
:
184 if (-1 == shmdt((char *) pvfb
->pXWDHeader
)) {
186 ErrorF("shmdt failed, %s", strerror(errno
));
190 case SHARED_MEMORY_FB
:
194 case NORMAL_MEMORY_FB
:
195 free(pvfb
->pXWDHeader
);
201 ddxGiveUp(enum ExitCode error
)
205 /* clean up the framebuffers */
206 for (i
= 0; i
< vfbNumScreens
; i
++) {
207 freeScreenInfo(&vfbScreens
[i
]);
213 DarwinHandleGUI(int argc
, char *argv
[])
224 OsVendorFatalError(const char *f
, va_list args
)
228 #if defined(DDXBEFORERESET)
237 /** This function is called in Xserver/os/inputthread.c when starting
240 ddxInputThreadInit(void)
248 ErrorF("-screen scrn WxHxD set screen's width, height, depth\n");
249 ErrorF("-pixdepths list-of-int support given pixmap depths\n");
250 ErrorF("+/-render turn on/off RENDER extension support"
252 ErrorF("-linebias n adjust thin line pixelization\n");
253 ErrorF("-blackpixel n pixel value for black\n");
254 ErrorF("-whitepixel n pixel value for white\n");
258 ("-fbdir directory put framebuffers in mmap'ed files in directory\n");
262 ErrorF("-shmem put framebuffers in shared memory\n");
267 ddxProcessArgument(int argc
, char *argv
[], int i
)
269 static Bool firstTime
= TRUE
;
270 static int lastScreen
= -1;
271 vfbScreenInfo
*currentScreen
;
274 vfbInitializePixmapDepths();
278 if (lastScreen
== -1)
279 currentScreen
= &defaultScreenInfo
;
281 currentScreen
= &vfbScreens
[lastScreen
];
283 if (strcmp(argv
[i
], "-screen") == 0) { /* -screen n WxHxD */
286 CHECK_FOR_REQUIRED_ARGUMENTS(2);
287 screenNum
= atoi(argv
[i
+ 1]);
288 /* The protocol only has a CARD8 for number of screens in the
289 connection setup block, so don't allow more than that. */
290 if ((screenNum
< 0) || (screenNum
>= 255)) {
291 ErrorF("Invalid screen number %d\n", screenNum
);
293 FatalError("Invalid screen number %d passed to -screen\n",
297 if (vfbNumScreens
<= screenNum
) {
299 reallocarray(vfbScreens
, screenNum
+ 1, sizeof(*vfbScreens
));
301 FatalError("Not enough memory for screen %d\n", screenNum
);
302 for (; vfbNumScreens
<= screenNum
; ++vfbNumScreens
)
303 vfbScreens
[vfbNumScreens
] = defaultScreenInfo
;
306 if (3 != sscanf(argv
[i
+ 2], "%dx%dx%d",
307 &vfbScreens
[screenNum
].width
,
308 &vfbScreens
[screenNum
].height
,
309 &vfbScreens
[screenNum
].depth
)) {
310 ErrorF("Invalid screen configuration %s\n", argv
[i
+ 2]);
312 FatalError("Invalid screen configuration %s for -screen %d\n",
313 argv
[i
+ 2], screenNum
);
316 lastScreen
= screenNum
;
320 if (strcmp(argv
[i
], "-pixdepths") == 0) { /* -pixdepths list-of-depth */
323 CHECK_FOR_REQUIRED_ARGUMENTS(1);
324 while ((++i
< argc
) && (depth
= atoi(argv
[i
])) != 0) {
325 if (depth
< 0 || depth
> 32) {
326 ErrorF("Invalid pixmap depth %d\n", depth
);
328 FatalError("Invalid pixmap depth %d passed to -pixdepths\n",
331 vfbPixmapDepths
[depth
] = TRUE
;
337 if (strcmp(argv
[i
], "+render") == 0) { /* +render */
342 if (strcmp(argv
[i
], "-render") == 0) { /* -render */
345 noCompositeExtension
= TRUE
;
350 if (strcmp(argv
[i
], "-blackpixel") == 0) { /* -blackpixel n */
351 CHECK_FOR_REQUIRED_ARGUMENTS(1);
352 currentScreen
->blackPixel
= atoi(argv
[++i
]);
356 if (strcmp(argv
[i
], "-whitepixel") == 0) { /* -whitepixel n */
357 CHECK_FOR_REQUIRED_ARGUMENTS(1);
358 currentScreen
->whitePixel
= atoi(argv
[++i
]);
362 if (strcmp(argv
[i
], "-linebias") == 0) { /* -linebias n */
363 CHECK_FOR_REQUIRED_ARGUMENTS(1);
364 currentScreen
->lineBias
= atoi(argv
[++i
]);
369 if (strcmp(argv
[i
], "-fbdir") == 0) { /* -fbdir directory */
370 CHECK_FOR_REQUIRED_ARGUMENTS(1);
372 fbmemtype
= MMAPPED_FILE_FB
;
375 #endif /* HAVE_MMAP */
378 if (strcmp(argv
[i
], "-shmem") == 0) { /* -shmem */
379 fbmemtype
= SHARED_MEMORY_FB
;
388 vfbInstallColormap(ColormapPtr pmap
)
390 ColormapPtr oldpmap
= GetInstalledmiColormap(pmap
->pScreen
);
392 if (pmap
!= oldpmap
) {
394 XWDFileHeader
*pXWDHeader
;
401 miInstallColormap(pmap
);
403 entries
= pmap
->pVisual
->ColormapEntries
;
404 pXWDHeader
= vfbScreens
[pmap
->pScreen
->myNum
].pXWDHeader
;
405 pVisual
= pmap
->pVisual
;
407 swapcopy32(pXWDHeader
->visual_class
, pVisual
->class);
408 swapcopy32(pXWDHeader
->red_mask
, pVisual
->redMask
);
409 swapcopy32(pXWDHeader
->green_mask
, pVisual
->greenMask
);
410 swapcopy32(pXWDHeader
->blue_mask
, pVisual
->blueMask
);
411 swapcopy32(pXWDHeader
->bits_per_rgb
, pVisual
->bitsPerRGBValue
);
412 swapcopy32(pXWDHeader
->colormap_entries
, pVisual
->ColormapEntries
);
414 ppix
= xallocarray(entries
, sizeof(Pixel
));
415 prgb
= xallocarray(entries
, sizeof(xrgb
));
416 defs
= xallocarray(entries
, sizeof(xColorItem
));
418 for (i
= 0; i
< entries
; i
++)
421 QueryColors(pmap
, entries
, ppix
, prgb
, serverClient
);
423 for (i
= 0; i
< entries
; i
++) { /* convert xrgbs to xColorItems */
424 defs
[i
].pixel
= ppix
[i
] & 0xff; /* change pixel to index */
425 defs
[i
].red
= prgb
[i
].red
;
426 defs
[i
].green
= prgb
[i
].green
;
427 defs
[i
].blue
= prgb
[i
].blue
;
428 defs
[i
].flags
= DoRed
| DoGreen
| DoBlue
;
430 (*pmap
->pScreen
->StoreColors
) (pmap
, entries
, defs
);
439 vfbStoreColors(ColormapPtr pmap
, int ndef
, xColorItem
* pdefs
)
444 if (pmap
!= GetInstalledmiColormap(pmap
->pScreen
)) {
448 pXWDCmap
= vfbScreens
[pmap
->pScreen
->myNum
].pXWDCmap
;
450 if ((pmap
->pVisual
->class | DynamicClass
) == DirectColor
) {
454 for (i
= 0; i
< ndef
; i
++) {
455 if (pdefs
[i
].flags
& DoRed
) {
456 swapcopy16(pXWDCmap
[pdefs
[i
].pixel
].red
, pdefs
[i
].red
);
458 if (pdefs
[i
].flags
& DoGreen
) {
459 swapcopy16(pXWDCmap
[pdefs
[i
].pixel
].green
, pdefs
[i
].green
);
461 if (pdefs
[i
].flags
& DoBlue
) {
462 swapcopy16(pXWDCmap
[pdefs
[i
].pixel
].blue
, pdefs
[i
].blue
);
469 /* this flushes any changes to the screens out to the mmapped file */
471 vfbBlockHandler(void *blockData
, void *timeout
)
475 for (i
= 0; i
< vfbNumScreens
; i
++) {
477 if (-1 == msync((caddr_t
) vfbScreens
[i
].pXWDHeader
,
478 (size_t) vfbScreens
[i
].sizeInBytes
, MS_ASYNC
))
480 /* silly NetBSD and who else? */
481 if (-1 == msync((caddr_t
) vfbScreens
[i
].pXWDHeader
,
482 (size_t) vfbScreens
[i
].sizeInBytes
))
486 ErrorF("msync failed, %s", strerror(errno
));
492 vfbWakeupHandler(void *blockData
, int result
)
497 vfbAllocateMmappedFramebuffer(vfbScreenInfoPtr pvfb
)
499 #define DUMMY_BUFFER_SIZE 65536
500 char dummyBuffer
[DUMMY_BUFFER_SIZE
];
501 int currentFileSize
, writeThisTime
;
503 snprintf(pvfb
->mmap_file
, sizeof(pvfb
->mmap_file
), "%s/Xvfb_screen%d",
504 pfbdir
, (int) (pvfb
- vfbScreens
));
505 if (-1 == (pvfb
->mmap_fd
= open(pvfb
->mmap_file
, O_CREAT
| O_RDWR
, 0666))) {
507 ErrorF("open %s failed, %s", pvfb
->mmap_file
, strerror(errno
));
511 /* Extend the file to be the proper size */
513 memset(dummyBuffer
, 0, DUMMY_BUFFER_SIZE
);
514 for (currentFileSize
= 0;
515 currentFileSize
< pvfb
->sizeInBytes
;
516 currentFileSize
+= writeThisTime
) {
517 writeThisTime
= min(DUMMY_BUFFER_SIZE
,
518 pvfb
->sizeInBytes
- currentFileSize
);
519 if (-1 == write(pvfb
->mmap_fd
, dummyBuffer
, writeThisTime
)) {
521 ErrorF("write %s failed, %s", pvfb
->mmap_file
, strerror(errno
));
526 /* try to mmap the file */
528 pvfb
->pXWDHeader
= (XWDFileHeader
*) mmap((caddr_t
) NULL
, pvfb
->sizeInBytes
,
529 PROT_READ
| PROT_WRITE
,
530 MAP_FILE
| MAP_SHARED
,
532 if (-1 == (long) pvfb
->pXWDHeader
) {
534 ErrorF("mmap %s failed, %s", pvfb
->mmap_file
, strerror(errno
));
535 pvfb
->pXWDHeader
= NULL
;
539 if (!RegisterBlockAndWakeupHandlers(vfbBlockHandler
, vfbWakeupHandler
,
541 pvfb
->pXWDHeader
= NULL
;
544 #endif /* HAVE_MMAP */
548 vfbAllocateSharedMemoryFramebuffer(vfbScreenInfoPtr pvfb
)
550 /* create the shared memory segment */
552 pvfb
->shmid
= shmget(IPC_PRIVATE
, pvfb
->sizeInBytes
, IPC_CREAT
| 0777);
553 if (pvfb
->shmid
< 0) {
555 ErrorF("shmget %d bytes failed, %s", pvfb
->sizeInBytes
,
560 /* try to attach it */
562 pvfb
->pXWDHeader
= (XWDFileHeader
*) shmat(pvfb
->shmid
, 0, 0);
563 if (-1 == (long) pvfb
->pXWDHeader
) {
565 ErrorF("shmat failed, %s", strerror(errno
));
566 pvfb
->pXWDHeader
= NULL
;
570 ErrorF("screen %d shmid %d\n", (int) (pvfb
- vfbScreens
), pvfb
->shmid
);
575 vfbAllocateFramebufferMemory(vfbScreenInfoPtr pvfb
)
578 return pvfb
->pfbMemory
; /* already done */
580 pvfb
->sizeInBytes
= pvfb
->paddedBytesWidth
* pvfb
->height
;
582 /* Calculate how many entries in colormap. This is rather bogus, because
583 * the visuals haven't even been set up yet, but we need to know because we
584 * have to allocate space in the file for the colormap. The number 10
585 * below comes from the MAX_PSEUDO_DEPTH define in cfbcmap.c.
588 if (pvfb
->depth
<= 10) { /* single index colormaps */
589 pvfb
->ncolors
= 1 << pvfb
->depth
;
591 else { /* decomposed colormaps */
592 int nplanes_per_color_component
= pvfb
->depth
/ 3;
595 nplanes_per_color_component
++;
596 pvfb
->ncolors
= 1 << nplanes_per_color_component
;
599 /* add extra bytes for XWDFileHeader, window name, and colormap */
601 pvfb
->sizeInBytes
+= SIZEOF(XWDheader
) + XWD_WINDOW_NAME_LEN
+
602 pvfb
->ncolors
* SIZEOF(XWDColor
);
604 pvfb
->pXWDHeader
= NULL
;
607 case MMAPPED_FILE_FB
:
608 vfbAllocateMmappedFramebuffer(pvfb
);
611 case MMAPPED_FILE_FB
:
616 case SHARED_MEMORY_FB
:
617 vfbAllocateSharedMemoryFramebuffer(pvfb
);
620 case SHARED_MEMORY_FB
:
624 case NORMAL_MEMORY_FB
:
625 pvfb
->pXWDHeader
= (XWDFileHeader
*) malloc(pvfb
->sizeInBytes
);
629 if (pvfb
->pXWDHeader
) {
630 pvfb
->pXWDCmap
= (XWDColor
*) ((char *) pvfb
->pXWDHeader
631 + SIZEOF(XWDheader
) +
632 XWD_WINDOW_NAME_LEN
);
633 pvfb
->pfbMemory
= (char *) (pvfb
->pXWDCmap
+ pvfb
->ncolors
);
635 return pvfb
->pfbMemory
;
642 vfbWriteXWDFileHeader(ScreenPtr pScreen
)
644 vfbScreenInfoPtr pvfb
= &vfbScreens
[pScreen
->myNum
];
645 XWDFileHeader
*pXWDHeader
= pvfb
->pXWDHeader
;
646 char hostname
[XWD_WINDOW_NAME_LEN
];
647 unsigned long swaptest
= 1;
650 needswap
= *(char *) &swaptest
;
652 pXWDHeader
->header_size
=
653 (char *) pvfb
->pXWDCmap
- (char *) pvfb
->pXWDHeader
;
654 pXWDHeader
->file_version
= XWD_FILE_VERSION
;
656 pXWDHeader
->pixmap_format
= ZPixmap
;
657 pXWDHeader
->pixmap_depth
= pvfb
->depth
;
658 pXWDHeader
->pixmap_height
= pXWDHeader
->window_height
= pvfb
->height
;
659 pXWDHeader
->xoffset
= 0;
660 pXWDHeader
->byte_order
= IMAGE_BYTE_ORDER
;
661 pXWDHeader
->bitmap_bit_order
= BITMAP_BIT_ORDER
;
662 #ifndef INTERNAL_VS_EXTERNAL_PADDING
663 pXWDHeader
->pixmap_width
= pXWDHeader
->window_width
= pvfb
->width
;
664 pXWDHeader
->bitmap_unit
= BITMAP_SCANLINE_UNIT
;
665 pXWDHeader
->bitmap_pad
= BITMAP_SCANLINE_PAD
;
667 pXWDHeader
->pixmap_width
= pXWDHeader
->window_width
= pvfb
->paddedWidth
;
668 pXWDHeader
->bitmap_unit
= BITMAP_SCANLINE_UNIT_PROTO
;
669 pXWDHeader
->bitmap_pad
= BITMAP_SCANLINE_PAD_PROTO
;
671 pXWDHeader
->bits_per_pixel
= pvfb
->bitsPerPixel
;
672 pXWDHeader
->bytes_per_line
= pvfb
->paddedBytesWidth
;
673 pXWDHeader
->ncolors
= pvfb
->ncolors
;
675 /* visual related fields are written when colormap is installed */
677 pXWDHeader
->window_x
= pXWDHeader
->window_y
= 0;
678 pXWDHeader
->window_bdrwidth
= 0;
680 /* write xwd "window" name: Xvfb hostname:server.screen */
682 if (-1 == gethostname(hostname
, sizeof(hostname
)))
685 hostname
[XWD_WINDOW_NAME_LEN
- 1] = 0;
686 sprintf((char *) (pXWDHeader
+ 1), "Xvfb %s:%s.%d", hostname
, display
,
689 /* write colormap pixel slot values */
691 for (i
= 0; i
< pvfb
->ncolors
; i
++) {
692 pvfb
->pXWDCmap
[i
].pixel
= i
;
695 /* byte swap to most significant byte first */
698 SwapLongs((CARD32
*) pXWDHeader
, SIZEOF(XWDheader
) / 4);
699 for (i
= 0; i
< pvfb
->ncolors
; i
++) {
700 swapl(&pvfb
->pXWDCmap
[i
].pixel
);
706 vfbCursorOffScreen(ScreenPtr
*ppScreen
, int *x
, int *y
)
712 vfbCrossScreen(ScreenPtr pScreen
, Bool entering
)
716 static miPointerScreenFuncRec vfbPointerCursorFuncs
= {
723 vfbCloseScreen(ScreenPtr pScreen
)
725 vfbScreenInfoPtr pvfb
= &vfbScreens
[pScreen
->myNum
];
727 pScreen
->CloseScreen
= pvfb
->closeScreen
;
730 * fb overwrites miCloseScreen, so do this here
732 if (pScreen
->devPrivate
)
733 (*pScreen
->DestroyPixmap
) (pScreen
->devPrivate
);
734 pScreen
->devPrivate
= NULL
;
736 return pScreen
->CloseScreen(pScreen
);
740 vfbRROutputValidateMode(ScreenPtr pScreen
,
746 if (pScrPriv
->minWidth
<= mode
->mode
.width
&&
747 pScrPriv
->maxWidth
>= mode
->mode
.width
&&
748 pScrPriv
->minHeight
<= mode
->mode
.height
&&
749 pScrPriv
->maxHeight
>= mode
->mode
.height
)
756 vfbRRScreenSetSize(ScreenPtr pScreen
,
762 rrScrPrivPtr pScrPriv
= rrGetScrPriv(pScreen
);
764 // Prevent screen updates while we change things around
765 SetRootClip(pScreen
, ROOT_CLIP_NONE
);
767 pScreen
->width
= width
;
768 pScreen
->height
= height
;
769 pScreen
->mmWidth
= mmWidth
;
770 pScreen
->mmHeight
= mmHeight
;
772 // Restore the ability to update screen, now with new dimensions
773 SetRootClip(pScreen
, ROOT_CLIP_FULL
);
775 RRScreenSizeNotify (pScreen
);
776 RRTellChanged(pScreen
);
778 return RROutputSetPhysicalSize(pScrPriv
->outputs
[pScreen
->myNum
], mmWidth
, mmHeight
);
782 vfbRRCrtcSet(ScreenPtr pScreen
,
789 RROutputPtr
*outputs
)
791 return RRCrtcNotify(crtc
, mode
, x
, y
, rotation
, NULL
, numOutput
, outputs
);
795 vfbRRGetInfo(ScreenPtr pScreen
, Rotation
*rotations
)
797 /* Don't support rotations */
798 *rotations
= RR_Rotate_0
;
804 vfbRandRInit(ScreenPtr pScreen
)
806 rrScrPrivPtr pScrPriv
;
807 #if RANDR_12_INTERFACE
811 xRRModeInfo modeInfo
;
814 int mmWidth
, mmHeight
;
816 if (!RRScreenInit (pScreen
))
818 pScrPriv
= rrGetScrPriv(pScreen
);
819 pScrPriv
->rrGetInfo
= vfbRRGetInfo
;
820 #if RANDR_12_INTERFACE
821 pScrPriv
->rrCrtcSet
= vfbRRCrtcSet
;
822 pScrPriv
->rrScreenSetSize
= vfbRRScreenSetSize
;
823 pScrPriv
->rrOutputSetProperty
= NULL
;
824 #if RANDR_13_INTERFACE
825 pScrPriv
->rrOutputGetProperty
= NULL
;
827 pScrPriv
->rrOutputValidateMode
= vfbRROutputValidateMode
;
828 pScrPriv
->rrModeDestroy
= NULL
;
830 mmWidth
= pScreen
->width
* 25.4 / monitorResolution
;
831 mmHeight
= pScreen
->height
* 25.4 / monitorResolution
;
833 RRScreenSetSizeRange (pScreen
,
835 pScreen
->width
, pScreen
->height
);
837 sprintf (name
, "%dx%d", pScreen
->width
, pScreen
->height
);
838 memset (&modeInfo
, '\0', sizeof (modeInfo
));
839 modeInfo
.width
= pScreen
->width
;
840 modeInfo
.height
= pScreen
->height
;
841 modeInfo
.nameLength
= strlen (name
);
843 mode
= RRModeGet (&modeInfo
, name
);
847 crtc
= RRCrtcCreate (pScreen
, NULL
);
851 /* This is to avoid xrandr to complain about the gamma missing */
852 RRCrtcGammaSetSize (crtc
, 256);
854 output
= RROutputCreate (pScreen
, "screen", 6, NULL
);
857 if (!RROutputSetClones (output
, NULL
, 0))
859 if (!RROutputSetModes (output
, &mode
, 1, 0))
861 if (!RROutputSetCrtcs (output
, &crtc
, 1))
863 if (!RROutputSetConnection (output
, RR_Connected
))
865 if (!RROutputSetPhysicalSize (output
, mmWidth
, mmHeight
))
867 RRCrtcNotify (crtc
, mode
, 0, 0, RR_Rotate_0
, NULL
, 1, &output
);
873 vfbScreenInit(ScreenPtr pScreen
, int argc
, char **argv
)
875 vfbScreenInfoPtr pvfb
= &vfbScreens
[pScreen
->myNum
];
876 int dpix
= monitorResolution
, dpiy
= monitorResolution
;
886 pvfb
->paddedBytesWidth
= PixmapBytePad(pvfb
->width
, pvfb
->depth
);
887 pvfb
->bitsPerPixel
= vfbBitsPerPixel(pvfb
->depth
);
888 if (pvfb
->bitsPerPixel
>= 8)
889 pvfb
->paddedWidth
= pvfb
->paddedBytesWidth
/ (pvfb
->bitsPerPixel
/ 8);
891 pvfb
->paddedWidth
= pvfb
->paddedBytesWidth
* 8;
892 pbits
= vfbAllocateFramebufferMemory(pvfb
);
896 switch (pvfb
->depth
) {
898 miSetVisualTypesAndMasks(8,
904 (1 << DirectColor
)), 8, PseudoColor
, 0, 0, 0);
907 miSetVisualTypesAndMasks(15,
910 8, TrueColor
, 0x7c00, 0x03e0, 0x001f);
913 miSetVisualTypesAndMasks(16,
916 8, TrueColor
, 0xf800, 0x07e0, 0x001f);
919 miSetVisualTypesAndMasks(24,
922 8, TrueColor
, 0xff0000, 0x00ff00, 0x0000ff);
925 miSetVisualTypesAndMasks(30,
928 10, TrueColor
, 0x3ff00000, 0x000ffc00,
937 ret
= fbScreenInit(pScreen
, pbits
, pvfb
->width
, pvfb
->height
,
938 dpix
, dpiy
, pvfb
->paddedWidth
, pvfb
->bitsPerPixel
);
940 fbPictureInit(pScreen
, 0, 0);
945 if (!vfbRandRInit(pScreen
))
948 pScreen
->InstallColormap
= vfbInstallColormap
;
949 pScreen
->StoreColors
= vfbStoreColors
;
951 miDCInitialize(pScreen
, &vfbPointerCursorFuncs
);
953 vfbWriteXWDFileHeader(pScreen
);
955 pScreen
->blackPixel
= pvfb
->blackPixel
;
956 pScreen
->whitePixel
= pvfb
->whitePixel
;
958 ret
= fbCreateDefColormap(pScreen
);
960 miSetZeroLineBias(pScreen
, pvfb
->lineBias
);
962 pvfb
->closeScreen
= pScreen
->CloseScreen
;
963 pScreen
->CloseScreen
= vfbCloseScreen
;
967 } /* end vfbScreenInit */
970 InitOutput(ScreenInfo
* screen_info
, int argc
, char **argv
)
975 if (!monitorResolution
)
976 monitorResolution
= 96;
978 /* initialize pixmap formats */
980 /* must have a pixmap depth to match every screen depth */
981 for (i
= 0; i
< vfbNumScreens
; i
++) {
982 vfbPixmapDepths
[vfbScreens
[i
].depth
] = TRUE
;
985 /* RENDER needs a good set of pixmaps. */
987 vfbPixmapDepths
[1] = TRUE
;
988 vfbPixmapDepths
[4] = TRUE
;
989 vfbPixmapDepths
[8] = TRUE
;
991 vfbPixmapDepths
[12] = TRUE
;
993 /* vfbPixmapDepths[15] = TRUE; */
994 vfbPixmapDepths
[16] = TRUE
;
995 vfbPixmapDepths
[24] = TRUE
;
997 vfbPixmapDepths
[30] = TRUE
;
999 vfbPixmapDepths
[32] = TRUE
;
1002 xorgGlxCreateVendor();
1004 for (i
= 1; i
<= 32; i
++) {
1005 if (vfbPixmapDepths
[i
]) {
1006 if (NumFormats
>= MAXFORMATS
)
1007 FatalError("MAXFORMATS is too small for this server\n");
1008 screen_info
->formats
[NumFormats
].depth
= i
;
1009 screen_info
->formats
[NumFormats
].bitsPerPixel
= vfbBitsPerPixel(i
);
1010 screen_info
->formats
[NumFormats
].scanlinePad
= BITMAP_SCANLINE_PAD
;
1015 screen_info
->imageByteOrder
= IMAGE_BYTE_ORDER
;
1016 screen_info
->bitmapScanlineUnit
= BITMAP_SCANLINE_UNIT
;
1017 screen_info
->bitmapScanlinePad
= BITMAP_SCANLINE_PAD
;
1018 screen_info
->bitmapBitOrder
= BITMAP_BIT_ORDER
;
1019 screen_info
->numPixmapFormats
= NumFormats
;
1021 /* initialize screens */
1023 if (vfbNumScreens
< 1) {
1024 vfbScreens
= &defaultScreenInfo
;
1027 for (i
= 0; i
< vfbNumScreens
; i
++) {
1028 if (-1 == AddScreen(vfbScreenInit
, argc
, argv
)) {
1029 FatalError("Couldn't add screen %d", i
);
1033 } /* end InitOutput */