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 #ifdef HAVE_DIX_CONFIG_H
30 #include <dix-config.h>
34 #include <X11/Xwinsock.h>
38 #include <X11/Xproto.h>
40 #include "scrnintstr.h"
44 #include "colormapst.h"
47 #include "mipointer.h"
49 #include <sys/types.h>
55 #endif /* HAVE_MMAP */
59 #include <sys/param.h>
61 #include <X11/XWDFile.h>
68 #include "glx_extinit.h"
70 #define VFB_DEFAULT_WIDTH 1280
71 #define VFB_DEFAULT_HEIGHT 1024
72 #define VFB_DEFAULT_DEPTH 8
73 #define VFB_DEFAULT_WHITEPIXEL 1
74 #define VFB_DEFAULT_BLACKPIXEL 0
75 #define VFB_DEFAULT_LINEBIAS 0
76 #define XWD_WINDOW_NAME_LEN 60
89 XWDFileHeader
*pXWDHeader
;
92 unsigned int lineBias
;
93 CloseScreenProcPtr closeScreen
;
97 char mmap_file
[MAXPATHLEN
];
103 } vfbScreenInfo
, *vfbScreenInfoPtr
;
105 static int vfbNumScreens
;
106 static vfbScreenInfo
*vfbScreens
;
108 static vfbScreenInfo defaultScreenInfo
= {
109 .width
= VFB_DEFAULT_WIDTH
,
110 .height
= VFB_DEFAULT_HEIGHT
,
111 .depth
= VFB_DEFAULT_DEPTH
,
112 .blackPixel
= VFB_DEFAULT_BLACKPIXEL
,
113 .whitePixel
= VFB_DEFAULT_WHITEPIXEL
,
114 .lineBias
= VFB_DEFAULT_LINEBIAS
,
117 static Bool vfbPixmapDepths
[33];
120 static char *pfbdir
= NULL
;
122 typedef enum { NORMAL_MEMORY_FB
, SHARED_MEMORY_FB
, MMAPPED_FILE_FB
} fbMemType
;
123 static fbMemType fbmemtype
= NORMAL_MEMORY_FB
;
124 static char needswap
= 0;
125 static Bool Render
= TRUE
;
127 #define swapcopy16(_dst, _src) \
128 if (needswap) { CARD16 _s = _src; cpswaps(_s, _dst); } \
131 #define swapcopy32(_dst, _src) \
132 if (needswap) { CARD32 _s = _src; cpswapl(_s, _dst); } \
136 vfbInitializePixmapDepths(void)
140 vfbPixmapDepths
[1] = TRUE
; /* always need bitmaps */
141 for (i
= 2; i
<= 32; i
++)
142 vfbPixmapDepths
[i
] = FALSE
;
146 vfbBitsPerPixel(int depth
)
152 else if (depth
<= 16)
159 ddxGiveUp(enum ExitCode error
)
163 /* clean up the framebuffers */
167 case MMAPPED_FILE_FB
:
168 for (i
= 0; i
< vfbNumScreens
; i
++) {
169 if (-1 == unlink(vfbScreens
[i
].mmap_file
)) {
171 ErrorF("unlink %s failed, %s",
172 vfbScreens
[i
].mmap_file
, strerror(errno
));
176 #else /* HAVE_MMAP */
177 case MMAPPED_FILE_FB
:
179 #endif /* HAVE_MMAP */
182 case SHARED_MEMORY_FB
:
183 for (i
= 0; i
< vfbNumScreens
; i
++) {
184 if (-1 == shmdt((char *) vfbScreens
[i
].pXWDHeader
)) {
186 ErrorF("shmdt failed, %s", strerror(errno
));
191 case SHARED_MEMORY_FB
:
195 case NORMAL_MEMORY_FB
:
196 for (i
= 0; i
< vfbNumScreens
; i
++) {
197 free(vfbScreens
[i
].pXWDHeader
);
204 AbortDDX(enum ExitCode error
)
211 DarwinHandleGUI(int argc
, char *argv
[])
222 OsVendorFatalError(const char *f
, va_list args
)
226 #if defined(DDXBEFORERESET)
237 ErrorF("-screen scrn WxHxD set screen's width, height, depth\n");
238 ErrorF("-pixdepths list-of-int support given pixmap depths\n");
239 ErrorF("+/-render turn on/off RENDER extension support"
241 ErrorF("-linebias n adjust thin line pixelization\n");
242 ErrorF("-blackpixel n pixel value for black\n");
243 ErrorF("-whitepixel n pixel value for white\n");
247 ("-fbdir directory put framebuffers in mmap'ed files in directory\n");
251 ErrorF("-shmem put framebuffers in shared memory\n");
256 ddxProcessArgument(int argc
, char *argv
[], int i
)
258 static Bool firstTime
= TRUE
;
259 static int lastScreen
= -1;
260 vfbScreenInfo
*currentScreen
;
263 vfbInitializePixmapDepths();
267 if (lastScreen
== -1)
268 currentScreen
= &defaultScreenInfo
;
270 currentScreen
= &vfbScreens
[lastScreen
];
272 #define CHECK_FOR_REQUIRED_ARGUMENTS(num) \
273 if (((i + num) >= argc) || (!argv[i + num])) { \
274 ErrorF("Required argument to %s not specified\n", argv[i]); \
276 FatalError("Required argument to %s not specified\n", argv[i]); \
279 if (strcmp(argv
[i
], "-screen") == 0) { /* -screen n WxHxD */
282 CHECK_FOR_REQUIRED_ARGUMENTS(2);
283 screenNum
= atoi(argv
[i
+ 1]);
284 /* The protocol only has a CARD8 for number of screens in the
285 connection setup block, so don't allow more than that. */
286 if ((screenNum
< 0) || (screenNum
>= 255)) {
287 ErrorF("Invalid screen number %d\n", screenNum
);
289 FatalError("Invalid screen number %d passed to -screen\n",
293 if (vfbNumScreens
<= screenNum
) {
295 realloc(vfbScreens
, sizeof(*vfbScreens
) * (screenNum
+ 1));
297 FatalError("Not enough memory for screen %d\n", screenNum
);
298 for (; vfbNumScreens
<= screenNum
; ++vfbNumScreens
)
299 vfbScreens
[vfbNumScreens
] = defaultScreenInfo
;
302 if (3 != sscanf(argv
[i
+ 2], "%dx%dx%d",
303 &vfbScreens
[screenNum
].width
,
304 &vfbScreens
[screenNum
].height
,
305 &vfbScreens
[screenNum
].depth
)) {
306 ErrorF("Invalid screen configuration %s\n", argv
[i
+ 2]);
308 FatalError("Invalid screen configuration %s for -screen %d\n",
309 argv
[i
+ 2], screenNum
);
312 lastScreen
= screenNum
;
316 if (strcmp(argv
[i
], "-pixdepths") == 0) { /* -pixdepths list-of-depth */
319 CHECK_FOR_REQUIRED_ARGUMENTS(1);
320 while ((++i
< argc
) && (depth
= atoi(argv
[i
])) != 0) {
321 if (depth
< 0 || depth
> 32) {
322 ErrorF("Invalid pixmap depth %d\n", depth
);
324 FatalError("Invalid pixmap depth %d passed to -pixdepths\n",
327 vfbPixmapDepths
[depth
] = TRUE
;
333 if (strcmp(argv
[i
], "+render") == 0) { /* +render */
338 if (strcmp(argv
[i
], "-render") == 0) { /* -render */
341 noCompositeExtension
= TRUE
;
346 if (strcmp(argv
[i
], "-blackpixel") == 0) { /* -blackpixel n */
347 CHECK_FOR_REQUIRED_ARGUMENTS(1);
348 currentScreen
->blackPixel
= atoi(argv
[++i
]);
352 if (strcmp(argv
[i
], "-whitepixel") == 0) { /* -whitepixel n */
353 CHECK_FOR_REQUIRED_ARGUMENTS(1);
354 currentScreen
->whitePixel
= atoi(argv
[++i
]);
358 if (strcmp(argv
[i
], "-linebias") == 0) { /* -linebias n */
359 CHECK_FOR_REQUIRED_ARGUMENTS(1);
360 currentScreen
->lineBias
= atoi(argv
[++i
]);
365 if (strcmp(argv
[i
], "-fbdir") == 0) { /* -fbdir directory */
366 CHECK_FOR_REQUIRED_ARGUMENTS(1);
368 fbmemtype
= MMAPPED_FILE_FB
;
371 #endif /* HAVE_MMAP */
374 if (strcmp(argv
[i
], "-shmem") == 0) { /* -shmem */
375 fbmemtype
= SHARED_MEMORY_FB
;
383 static DevPrivateKeyRec cmapScrPrivateKeyRec
;
385 #define cmapScrPrivateKey (&cmapScrPrivateKeyRec)
387 #define GetInstalledColormap(s) ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, cmapScrPrivateKey))
388 #define SetInstalledColormap(s,c) (dixSetPrivate(&(s)->devPrivates, cmapScrPrivateKey, c))
391 vfbListInstalledColormaps(ScreenPtr pScreen
, Colormap
* pmaps
)
393 /* By the time we are processing requests, we can guarantee that there
394 * is always a colormap installed */
395 *pmaps
= GetInstalledColormap(pScreen
)->mid
;
400 vfbInstallColormap(ColormapPtr pmap
)
402 ColormapPtr oldpmap
= GetInstalledColormap(pmap
->pScreen
);
404 if (pmap
!= oldpmap
) {
406 XWDFileHeader
*pXWDHeader
;
414 if (oldpmap
!= (ColormapPtr
) None
)
415 WalkTree(pmap
->pScreen
, TellLostMap
, (char *) &oldpmap
->mid
);
417 SetInstalledColormap(pmap
->pScreen
, pmap
);
418 WalkTree(pmap
->pScreen
, TellGainedMap
, (char *) &pmap
->mid
);
420 entries
= pmap
->pVisual
->ColormapEntries
;
421 pXWDHeader
= vfbScreens
[pmap
->pScreen
->myNum
].pXWDHeader
;
422 pXWDCmap
= vfbScreens
[pmap
->pScreen
->myNum
].pXWDCmap
;
423 pVisual
= pmap
->pVisual
;
425 swapcopy32(pXWDHeader
->visual_class
, pVisual
->class);
426 swapcopy32(pXWDHeader
->red_mask
, pVisual
->redMask
);
427 swapcopy32(pXWDHeader
->green_mask
, pVisual
->greenMask
);
428 swapcopy32(pXWDHeader
->blue_mask
, pVisual
->blueMask
);
429 swapcopy32(pXWDHeader
->bits_per_rgb
, pVisual
->bitsPerRGBValue
);
430 swapcopy32(pXWDHeader
->colormap_entries
, pVisual
->ColormapEntries
);
432 ppix
= (Pixel
*) malloc(entries
* sizeof(Pixel
));
433 prgb
= (xrgb
*) malloc(entries
* sizeof(xrgb
));
434 defs
= (xColorItem
*) malloc(entries
* sizeof(xColorItem
));
436 for (i
= 0; i
< entries
; i
++)
439 QueryColors(pmap
, entries
, ppix
, prgb
, serverClient
);
441 for (i
= 0; i
< entries
; i
++) { /* convert xrgbs to xColorItems */
442 defs
[i
].pixel
= ppix
[i
] & 0xff; /* change pixel to index */
443 defs
[i
].red
= prgb
[i
].red
;
444 defs
[i
].green
= prgb
[i
].green
;
445 defs
[i
].blue
= prgb
[i
].blue
;
446 defs
[i
].flags
= DoRed
| DoGreen
| DoBlue
;
448 (*pmap
->pScreen
->StoreColors
) (pmap
, entries
, defs
);
457 vfbUninstallColormap(ColormapPtr pmap
)
459 ColormapPtr curpmap
= GetInstalledColormap(pmap
->pScreen
);
461 if (pmap
== curpmap
) {
462 if (pmap
->mid
!= pmap
->pScreen
->defColormap
) {
463 dixLookupResourceByType((pointer
*) &curpmap
,
464 pmap
->pScreen
->defColormap
,
465 RT_COLORMAP
, serverClient
,
467 (*pmap
->pScreen
->InstallColormap
) (curpmap
);
473 vfbStoreColors(ColormapPtr pmap
, int ndef
, xColorItem
* pdefs
)
478 if (pmap
!= GetInstalledColormap(pmap
->pScreen
)) {
482 pXWDCmap
= vfbScreens
[pmap
->pScreen
->myNum
].pXWDCmap
;
484 if ((pmap
->pVisual
->class | DynamicClass
) == DirectColor
) {
488 for (i
= 0; i
< ndef
; i
++) {
489 if (pdefs
[i
].flags
& DoRed
) {
490 swapcopy16(pXWDCmap
[pdefs
[i
].pixel
].red
, pdefs
[i
].red
);
492 if (pdefs
[i
].flags
& DoGreen
) {
493 swapcopy16(pXWDCmap
[pdefs
[i
].pixel
].green
, pdefs
[i
].green
);
495 if (pdefs
[i
].flags
& DoBlue
) {
496 swapcopy16(pXWDCmap
[pdefs
[i
].pixel
].blue
, pdefs
[i
].blue
);
502 vfbSaveScreen(ScreenPtr pScreen
, int on
)
509 /* this flushes any changes to the screens out to the mmapped file */
511 vfbBlockHandler(pointer blockData
, OSTimePtr pTimeout
, pointer pReadmask
)
515 for (i
= 0; i
< vfbNumScreens
; i
++) {
517 if (-1 == msync((caddr_t
) vfbScreens
[i
].pXWDHeader
,
518 (size_t) vfbScreens
[i
].sizeInBytes
, MS_ASYNC
))
520 /* silly NetBSD and who else? */
521 if (-1 == msync((caddr_t
) vfbScreens
[i
].pXWDHeader
,
522 (size_t) vfbScreens
[i
].sizeInBytes
))
526 ErrorF("msync failed, %s", strerror(errno
));
532 vfbWakeupHandler(pointer blockData
, int result
, pointer pReadmask
)
537 vfbAllocateMmappedFramebuffer(vfbScreenInfoPtr pvfb
)
539 #define DUMMY_BUFFER_SIZE 65536
540 char dummyBuffer
[DUMMY_BUFFER_SIZE
];
541 int currentFileSize
, writeThisTime
;
543 snprintf(pvfb
->mmap_file
, sizeof(pvfb
->mmap_file
), "%s/Xvfb_screen%d",
544 pfbdir
, (int) (pvfb
- vfbScreens
));
545 if (-1 == (pvfb
->mmap_fd
= open(pvfb
->mmap_file
, O_CREAT
| O_RDWR
, 0666))) {
547 ErrorF("open %s failed, %s", pvfb
->mmap_file
, strerror(errno
));
551 /* Extend the file to be the proper size */
553 memset(dummyBuffer
, 0, DUMMY_BUFFER_SIZE
);
554 for (currentFileSize
= 0;
555 currentFileSize
< pvfb
->sizeInBytes
;
556 currentFileSize
+= writeThisTime
) {
557 writeThisTime
= min(DUMMY_BUFFER_SIZE
,
558 pvfb
->sizeInBytes
- currentFileSize
);
559 if (-1 == write(pvfb
->mmap_fd
, dummyBuffer
, writeThisTime
)) {
561 ErrorF("write %s failed, %s", pvfb
->mmap_file
, strerror(errno
));
566 /* try to mmap the file */
568 pvfb
->pXWDHeader
= (XWDFileHeader
*) mmap((caddr_t
) NULL
, pvfb
->sizeInBytes
,
569 PROT_READ
| PROT_WRITE
,
570 MAP_FILE
| MAP_SHARED
,
572 if (-1 == (long) pvfb
->pXWDHeader
) {
574 ErrorF("mmap %s failed, %s", pvfb
->mmap_file
, strerror(errno
));
575 pvfb
->pXWDHeader
= NULL
;
579 if (!RegisterBlockAndWakeupHandlers(vfbBlockHandler
, vfbWakeupHandler
,
581 pvfb
->pXWDHeader
= NULL
;
584 #endif /* HAVE_MMAP */
588 vfbAllocateSharedMemoryFramebuffer(vfbScreenInfoPtr pvfb
)
590 /* create the shared memory segment */
592 pvfb
->shmid
= shmget(IPC_PRIVATE
, pvfb
->sizeInBytes
, IPC_CREAT
| 0777);
593 if (pvfb
->shmid
< 0) {
595 ErrorF("shmget %d bytes failed, %s", pvfb
->sizeInBytes
,
600 /* try to attach it */
602 pvfb
->pXWDHeader
= (XWDFileHeader
*) shmat(pvfb
->shmid
, 0, 0);
603 if (-1 == (long) pvfb
->pXWDHeader
) {
605 ErrorF("shmat failed, %s", strerror(errno
));
606 pvfb
->pXWDHeader
= NULL
;
610 ErrorF("screen %d shmid %d\n", (int) (pvfb
- vfbScreens
), pvfb
->shmid
);
615 vfbAllocateFramebufferMemory(vfbScreenInfoPtr pvfb
)
618 return pvfb
->pfbMemory
; /* already done */
620 pvfb
->sizeInBytes
= pvfb
->paddedBytesWidth
* pvfb
->height
;
622 /* Calculate how many entries in colormap. This is rather bogus, because
623 * the visuals haven't even been set up yet, but we need to know because we
624 * have to allocate space in the file for the colormap. The number 10
625 * below comes from the MAX_PSEUDO_DEPTH define in cfbcmap.c.
628 if (pvfb
->depth
<= 10) { /* single index colormaps */
629 pvfb
->ncolors
= 1 << pvfb
->depth
;
631 else { /* decomposed colormaps */
632 int nplanes_per_color_component
= pvfb
->depth
/ 3;
635 nplanes_per_color_component
++;
636 pvfb
->ncolors
= 1 << nplanes_per_color_component
;
639 /* add extra bytes for XWDFileHeader, window name, and colormap */
641 pvfb
->sizeInBytes
+= SIZEOF(XWDheader
) + XWD_WINDOW_NAME_LEN
+
642 pvfb
->ncolors
* SIZEOF(XWDColor
);
644 pvfb
->pXWDHeader
= NULL
;
647 case MMAPPED_FILE_FB
:
648 vfbAllocateMmappedFramebuffer(pvfb
);
651 case MMAPPED_FILE_FB
:
656 case SHARED_MEMORY_FB
:
657 vfbAllocateSharedMemoryFramebuffer(pvfb
);
660 case SHARED_MEMORY_FB
:
664 case NORMAL_MEMORY_FB
:
665 pvfb
->pXWDHeader
= (XWDFileHeader
*) malloc(pvfb
->sizeInBytes
);
669 if (pvfb
->pXWDHeader
) {
670 pvfb
->pXWDCmap
= (XWDColor
*) ((char *) pvfb
->pXWDHeader
671 + SIZEOF(XWDheader
) +
672 XWD_WINDOW_NAME_LEN
);
673 pvfb
->pfbMemory
= (char *) (pvfb
->pXWDCmap
+ pvfb
->ncolors
);
675 return pvfb
->pfbMemory
;
682 vfbWriteXWDFileHeader(ScreenPtr pScreen
)
684 vfbScreenInfoPtr pvfb
= &vfbScreens
[pScreen
->myNum
];
685 XWDFileHeader
*pXWDHeader
= pvfb
->pXWDHeader
;
686 char hostname
[XWD_WINDOW_NAME_LEN
];
687 unsigned long swaptest
= 1;
690 needswap
= *(char *) &swaptest
;
692 pXWDHeader
->header_size
=
693 (char *) pvfb
->pXWDCmap
- (char *) pvfb
->pXWDHeader
;
694 pXWDHeader
->file_version
= XWD_FILE_VERSION
;
696 pXWDHeader
->pixmap_format
= ZPixmap
;
697 pXWDHeader
->pixmap_depth
= pvfb
->depth
;
698 pXWDHeader
->pixmap_height
= pXWDHeader
->window_height
= pvfb
->height
;
699 pXWDHeader
->xoffset
= 0;
700 pXWDHeader
->byte_order
= IMAGE_BYTE_ORDER
;
701 pXWDHeader
->bitmap_bit_order
= BITMAP_BIT_ORDER
;
702 #ifndef INTERNAL_VS_EXTERNAL_PADDING
703 pXWDHeader
->pixmap_width
= pXWDHeader
->window_width
= pvfb
->width
;
704 pXWDHeader
->bitmap_unit
= BITMAP_SCANLINE_UNIT
;
705 pXWDHeader
->bitmap_pad
= BITMAP_SCANLINE_PAD
;
707 pXWDHeader
->pixmap_width
= pXWDHeader
->window_width
= pvfb
->paddedWidth
;
708 pXWDHeader
->bitmap_unit
= BITMAP_SCANLINE_UNIT_PROTO
;
709 pXWDHeader
->bitmap_pad
= BITMAP_SCANLINE_PAD_PROTO
;
711 pXWDHeader
->bits_per_pixel
= pvfb
->bitsPerPixel
;
712 pXWDHeader
->bytes_per_line
= pvfb
->paddedBytesWidth
;
713 pXWDHeader
->ncolors
= pvfb
->ncolors
;
715 /* visual related fields are written when colormap is installed */
717 pXWDHeader
->window_x
= pXWDHeader
->window_y
= 0;
718 pXWDHeader
->window_bdrwidth
= 0;
720 /* write xwd "window" name: Xvfb hostname:server.screen */
722 if (-1 == gethostname(hostname
, sizeof(hostname
)))
725 hostname
[XWD_WINDOW_NAME_LEN
- 1] = 0;
726 sprintf((char *) (pXWDHeader
+ 1), "Xvfb %s:%s.%d", hostname
, display
,
729 /* write colormap pixel slot values */
731 for (i
= 0; i
< pvfb
->ncolors
; i
++) {
732 pvfb
->pXWDCmap
[i
].pixel
= i
;
735 /* byte swap to most significant byte first */
738 SwapLongs((CARD32
*) pXWDHeader
, SIZEOF(XWDheader
) / 4);
739 for (i
= 0; i
< pvfb
->ncolors
; i
++) {
740 swapl(&pvfb
->pXWDCmap
[i
].pixel
);
746 vfbCursorOffScreen(ScreenPtr
*ppScreen
, int *x
, int *y
)
752 vfbCrossScreen(ScreenPtr pScreen
, Bool entering
)
756 static miPointerScreenFuncRec vfbPointerCursorFuncs
= {
763 vfbCloseScreen(ScreenPtr pScreen
)
765 vfbScreenInfoPtr pvfb
= &vfbScreens
[pScreen
->myNum
];
768 pScreen
->CloseScreen
= pvfb
->closeScreen
;
771 * XXX probably lots of stuff to clean. For now,
772 * clear installed colormaps so that server reset works correctly.
774 for (i
= 0; i
< screenInfo
.numScreens
; i
++)
775 SetInstalledColormap(screenInfo
.screens
[i
], NULL
);
778 * fb overwrites miCloseScreen, so do this here
780 if (pScreen
->devPrivate
)
781 (*pScreen
->DestroyPixmap
) (pScreen
->devPrivate
);
782 pScreen
->devPrivate
= NULL
;
784 return pScreen
->CloseScreen(pScreen
);
788 vfbScreenInit(ScreenPtr pScreen
, int argc
, char **argv
)
790 vfbScreenInfoPtr pvfb
= &vfbScreens
[pScreen
->myNum
];
791 int dpix
= monitorResolution
, dpiy
= monitorResolution
;
795 if (!dixRegisterPrivateKey(&cmapScrPrivateKeyRec
, PRIVATE_SCREEN
, 0))
804 pvfb
->paddedBytesWidth
= PixmapBytePad(pvfb
->width
, pvfb
->depth
);
805 pvfb
->bitsPerPixel
= vfbBitsPerPixel(pvfb
->depth
);
806 if (pvfb
->bitsPerPixel
>= 8)
807 pvfb
->paddedWidth
= pvfb
->paddedBytesWidth
/ (pvfb
->bitsPerPixel
/ 8);
809 pvfb
->paddedWidth
= pvfb
->paddedBytesWidth
* 8;
810 pbits
= vfbAllocateFramebufferMemory(pvfb
);
814 switch (pvfb
->depth
) {
816 miSetVisualTypesAndMasks(8,
822 (1 << DirectColor
)), 8, PseudoColor
, 0, 0, 0);
825 miSetVisualTypesAndMasks(15,
828 8, TrueColor
, 0x7c00, 0x03e0, 0x001f);
831 miSetVisualTypesAndMasks(16,
834 8, TrueColor
, 0xf800, 0x07e0, 0x001f);
837 miSetVisualTypesAndMasks(24,
840 8, TrueColor
, 0xff0000, 0x00ff00, 0x0000ff);
843 miSetVisualTypesAndMasks(30,
846 10, TrueColor
, 0x3ff00000, 0x000ffc00,
855 ret
= fbScreenInit(pScreen
, pbits
, pvfb
->width
, pvfb
->height
,
856 dpix
, dpiy
, pvfb
->paddedWidth
, pvfb
->bitsPerPixel
);
858 fbPictureInit(pScreen
, 0, 0);
863 pScreen
->InstallColormap
= vfbInstallColormap
;
864 pScreen
->UninstallColormap
= vfbUninstallColormap
;
865 pScreen
->ListInstalledColormaps
= vfbListInstalledColormaps
;
867 pScreen
->SaveScreen
= vfbSaveScreen
;
868 pScreen
->StoreColors
= vfbStoreColors
;
870 miDCInitialize(pScreen
, &vfbPointerCursorFuncs
);
872 vfbWriteXWDFileHeader(pScreen
);
874 pScreen
->blackPixel
= pvfb
->blackPixel
;
875 pScreen
->whitePixel
= pvfb
->whitePixel
;
877 ret
= fbCreateDefColormap(pScreen
);
879 miSetZeroLineBias(pScreen
, pvfb
->lineBias
);
881 pvfb
->closeScreen
= pScreen
->CloseScreen
;
882 pScreen
->CloseScreen
= vfbCloseScreen
;
886 } /* end vfbScreenInit */
888 static const ExtensionModule vfbExtensions
[] = {
890 { GlxExtensionInit
, "GLX", &noGlxExtension
},
895 void vfbExtensionInit(void)
899 for (i
= 0; i
< ARRAY_SIZE(vfbExtensions
); i
++)
900 LoadExtension(&vfbExtensions
[i
], TRUE
);
904 InitOutput(ScreenInfo
* screenInfo
, int argc
, char **argv
)
909 if (serverGeneration
== 1)
912 /* initialize pixmap formats */
914 /* must have a pixmap depth to match every screen depth */
915 for (i
= 0; i
< vfbNumScreens
; i
++) {
916 vfbPixmapDepths
[vfbScreens
[i
].depth
] = TRUE
;
919 /* RENDER needs a good set of pixmaps. */
921 vfbPixmapDepths
[1] = TRUE
;
922 vfbPixmapDepths
[4] = TRUE
;
923 vfbPixmapDepths
[8] = TRUE
;
925 vfbPixmapDepths
[12] = TRUE
;
927 /* vfbPixmapDepths[15] = TRUE; */
928 vfbPixmapDepths
[16] = TRUE
;
929 vfbPixmapDepths
[24] = TRUE
;
931 vfbPixmapDepths
[30] = TRUE
;
933 vfbPixmapDepths
[32] = TRUE
;
936 for (i
= 1; i
<= 32; i
++) {
937 if (vfbPixmapDepths
[i
]) {
938 if (NumFormats
>= MAXFORMATS
)
939 FatalError("MAXFORMATS is too small for this server\n");
940 screenInfo
->formats
[NumFormats
].depth
= i
;
941 screenInfo
->formats
[NumFormats
].bitsPerPixel
= vfbBitsPerPixel(i
);
942 screenInfo
->formats
[NumFormats
].scanlinePad
= BITMAP_SCANLINE_PAD
;
947 screenInfo
->imageByteOrder
= IMAGE_BYTE_ORDER
;
948 screenInfo
->bitmapScanlineUnit
= BITMAP_SCANLINE_UNIT
;
949 screenInfo
->bitmapScanlinePad
= BITMAP_SCANLINE_PAD
;
950 screenInfo
->bitmapBitOrder
= BITMAP_BIT_ORDER
;
951 screenInfo
->numPixmapFormats
= NumFormats
;
953 /* initialize screens */
955 if (vfbNumScreens
< 1) {
956 vfbScreens
= &defaultScreenInfo
;
959 for (i
= 0; i
< vfbNumScreens
; i
++) {
960 if (-1 == AddScreen(vfbScreenInit
, argc
, argv
)) {
961 FatalError("Couldn't add screen %d", i
);
965 } /* end InitOutput */