First import
[xorg_rtime.git] / xorg-server-1.4 / hw / vfb / InitOutput.c
bloba2d8661184928af5704f88f90f293da17d633de5
1 /*
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
9 documentation.
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
25 from The Open Group.
29 #ifdef HAVE_DIX_CONFIG_H
30 #include <dix-config.h>
31 #endif
33 #if defined(WIN32)
34 #include <X11/Xwinsock.h>
35 #endif
36 #include <stdio.h>
37 #include <X11/X.h>
38 #define NEED_EVENTS
39 #include <X11/Xproto.h>
40 #include <X11/Xos.h>
41 #include "scrnintstr.h"
42 #include "servermd.h"
43 #define PSZ 8
44 #include "fb.h"
45 #include "mibstore.h"
46 #include "colormapst.h"
47 #include "gcstruct.h"
48 #include "input.h"
49 #include "mipointer.h"
50 #include "micmap.h"
51 #include <sys/types.h>
52 #ifdef HAS_MMAP
53 #include <sys/mman.h>
54 #ifndef MAP_FILE
55 #define MAP_FILE 0
56 #endif
57 #endif /* HAS_MMAP */
58 #include <sys/stat.h>
59 #include <errno.h>
60 #ifndef WIN32
61 #include <sys/param.h>
62 #endif
63 #include <X11/XWDFile.h>
64 #ifdef HAS_SHM
65 #include <sys/ipc.h>
66 #include <sys/shm.h>
67 #endif /* HAS_SHM */
68 #include "dix.h"
69 #include "miline.h"
71 #define VFB_DEFAULT_WIDTH 1280
72 #define VFB_DEFAULT_HEIGHT 1024
73 #define VFB_DEFAULT_DEPTH 8
74 #define VFB_DEFAULT_WHITEPIXEL 1
75 #define VFB_DEFAULT_BLACKPIXEL 0
76 #define VFB_DEFAULT_LINEBIAS 0
77 #define XWD_WINDOW_NAME_LEN 60
79 typedef struct
81 int scrnum;
82 int width;
83 int paddedBytesWidth;
84 int paddedWidth;
85 int height;
86 int depth;
87 int bitsPerPixel;
88 int sizeInBytes;
89 int ncolors;
90 char *pfbMemory;
91 XWDColor *pXWDCmap;
92 XWDFileHeader *pXWDHeader;
93 Pixel blackPixel;
94 Pixel whitePixel;
95 unsigned int lineBias;
96 CloseScreenProcPtr closeScreen;
98 #ifdef HAS_MMAP
99 int mmap_fd;
100 char mmap_file[MAXPATHLEN];
101 #endif
103 #ifdef HAS_SHM
104 int shmid;
105 #endif
106 } vfbScreenInfo, *vfbScreenInfoPtr;
108 static int vfbNumScreens;
109 static vfbScreenInfo vfbScreens[MAXSCREENS];
110 static Bool vfbPixmapDepths[33];
111 #ifdef HAS_MMAP
112 static char *pfbdir = NULL;
113 #endif
114 typedef enum { NORMAL_MEMORY_FB, SHARED_MEMORY_FB, MMAPPED_FILE_FB } fbMemType;
115 static fbMemType fbmemtype = NORMAL_MEMORY_FB;
116 static char needswap = 0;
117 static int lastScreen = -1;
118 static Bool Render = TRUE;
120 #define swapcopy16(_dst, _src) \
121 if (needswap) { CARD16 _s = _src; cpswaps(_s, _dst); } \
122 else _dst = _src;
124 #define swapcopy32(_dst, _src) \
125 if (needswap) { CARD32 _s = _src; cpswapl(_s, _dst); } \
126 else _dst = _src;
129 static void
130 vfbInitializePixmapDepths(void)
132 int i;
133 vfbPixmapDepths[1] = TRUE; /* always need bitmaps */
134 for (i = 2; i <= 32; i++)
135 vfbPixmapDepths[i] = FALSE;
138 static void
139 vfbInitializeDefaultScreens(void)
141 int i;
143 for (i = 0; i < MAXSCREENS; i++)
145 vfbScreens[i].scrnum = i;
146 vfbScreens[i].width = VFB_DEFAULT_WIDTH;
147 vfbScreens[i].height = VFB_DEFAULT_HEIGHT;
148 vfbScreens[i].depth = VFB_DEFAULT_DEPTH;
149 vfbScreens[i].blackPixel = VFB_DEFAULT_BLACKPIXEL;
150 vfbScreens[i].whitePixel = VFB_DEFAULT_WHITEPIXEL;
151 vfbScreens[i].lineBias = VFB_DEFAULT_LINEBIAS;
152 vfbScreens[i].pfbMemory = NULL;
154 vfbNumScreens = 1;
157 static int
158 vfbBitsPerPixel(int depth)
160 if (depth == 1) return 1;
161 else if (depth <= 8) return 8;
162 else if (depth <= 16) return 16;
163 else return 32;
166 void
167 ddxGiveUp()
169 int i;
171 /* clean up the framebuffers */
173 switch (fbmemtype)
175 #ifdef HAS_MMAP
176 case MMAPPED_FILE_FB:
177 for (i = 0; i < vfbNumScreens; i++)
179 if (-1 == unlink(vfbScreens[i].mmap_file))
181 perror("unlink");
182 ErrorF("unlink %s failed, errno %d",
183 vfbScreens[i].mmap_file, errno);
186 break;
187 #else /* HAS_MMAP */
188 case MMAPPED_FILE_FB:
189 break;
190 #endif /* HAS_MMAP */
192 #ifdef HAS_SHM
193 case SHARED_MEMORY_FB:
194 for (i = 0; i < vfbNumScreens; i++)
196 if (-1 == shmdt((char *)vfbScreens[i].pXWDHeader))
198 perror("shmdt");
199 ErrorF("shmdt failed, errno %d", errno);
202 break;
203 #else /* HAS_SHM */
204 case SHARED_MEMORY_FB:
205 break;
206 #endif /* HAS_SHM */
208 case NORMAL_MEMORY_FB:
209 for (i = 0; i < vfbNumScreens; i++)
211 Xfree(vfbScreens[i].pXWDHeader);
213 break;
217 void
218 AbortDDX()
220 ddxGiveUp();
223 #ifdef __DARWIN__
224 void
225 DarwinHandleGUI(int argc, char *argv[])
229 void GlxExtensionInit();
230 void GlxWrapInitVisuals(void *procPtr);
232 void
233 DarwinGlxExtensionInit()
235 GlxExtensionInit();
238 void
239 DarwinGlxWrapInitVisuals(
240 void *procPtr)
242 GlxWrapInitVisuals(procPtr);
244 #endif
246 void
247 OsVendorInit()
251 void
252 OsVendorFatalError()
256 #if defined(DDXBEFORERESET)
257 void ddxBeforeReset(void)
259 return;
261 #endif
263 void
264 ddxUseMsg()
266 ErrorF("-screen scrn WxHxD set screen's width, height, depth\n");
267 ErrorF("-pixdepths list-of-int support given pixmap depths\n");
268 #ifdef RENDER
269 ErrorF("+/-render turn on/of RENDER extension support"
270 "(default on)\n");
271 #endif
272 ErrorF("-linebias n adjust thin line pixelization\n");
273 ErrorF("-blackpixel n pixel value for black\n");
274 ErrorF("-whitepixel n pixel value for white\n");
276 #ifdef HAS_MMAP
277 ErrorF("-fbdir directory put framebuffers in mmap'ed files in directory\n");
278 #endif
280 #ifdef HAS_SHM
281 ErrorF("-shmem put framebuffers in shared memory\n");
282 #endif
285 /* ddxInitGlobals - called by |InitGlobals| from os/util.c */
286 void ddxInitGlobals(void)
291 ddxProcessArgument(int argc, char *argv[], int i)
293 static Bool firstTime = TRUE;
295 if (firstTime)
297 vfbInitializeDefaultScreens();
298 vfbInitializePixmapDepths();
299 firstTime = FALSE;
302 #define CHECK_FOR_REQUIRED_ARGUMENTS(num) \
303 if (((i + num) >= argc) || (!argv[i + num])) { \
304 ErrorF("Required argument to %s not specified\n", argv[i]); \
305 UseMsg(); \
306 FatalError("Required argument to %s not specified\n", argv[i]); \
309 if (strcmp (argv[i], "-screen") == 0) /* -screen n WxHxD */
311 int screenNum;
312 CHECK_FOR_REQUIRED_ARGUMENTS(2);
313 screenNum = atoi(argv[i+1]);
314 if (screenNum < 0 || screenNum >= MAXSCREENS)
316 ErrorF("Invalid screen number %d\n", screenNum);
317 UseMsg();
318 FatalError("Invalid screen number %d passed to -screen\n",
319 screenNum);
321 if (3 != sscanf(argv[i+2], "%dx%dx%d",
322 &vfbScreens[screenNum].width,
323 &vfbScreens[screenNum].height,
324 &vfbScreens[screenNum].depth))
326 ErrorF("Invalid screen configuration %s\n", argv[i+2]);
327 UseMsg();
328 FatalError("Invalid screen configuration %s for -screen %d\n",
329 argv[i+2], screenNum);
332 if (screenNum >= vfbNumScreens)
333 vfbNumScreens = screenNum + 1;
334 lastScreen = screenNum;
335 return 3;
338 if (strcmp (argv[i], "-pixdepths") == 0) /* -pixdepths list-of-depth */
340 int depth, ret = 1;
342 CHECK_FOR_REQUIRED_ARGUMENTS(1);
343 while ((++i < argc) && (depth = atoi(argv[i])) != 0)
345 if (depth < 0 || depth > 32)
347 ErrorF("Invalid pixmap depth %d\n", depth);
348 UseMsg();
349 FatalError("Invalid pixmap depth %d passed to -pixdepths\n",
350 depth);
352 vfbPixmapDepths[depth] = TRUE;
353 ret++;
355 return ret;
358 if (strcmp (argv[i], "+render") == 0) /* +render */
360 Render = TRUE;
361 return 1;
364 if (strcmp (argv[i], "-render") == 0) /* -render */
366 Render = FALSE;
367 #ifdef COMPOSITE
368 noCompositeExtension = TRUE;
369 #endif
370 return 1;
373 if (strcmp (argv[i], "-blackpixel") == 0) /* -blackpixel n */
375 Pixel pix;
376 CHECK_FOR_REQUIRED_ARGUMENTS(1);
377 pix = atoi(argv[++i]);
378 if (-1 == lastScreen)
380 int i;
381 for (i = 0; i < MAXSCREENS; i++)
383 vfbScreens[i].blackPixel = pix;
386 else
388 vfbScreens[lastScreen].blackPixel = pix;
390 return 2;
393 if (strcmp (argv[i], "-whitepixel") == 0) /* -whitepixel n */
395 Pixel pix;
396 CHECK_FOR_REQUIRED_ARGUMENTS(1);
397 pix = atoi(argv[++i]);
398 if (-1 == lastScreen)
400 int i;
401 for (i = 0; i < MAXSCREENS; i++)
403 vfbScreens[i].whitePixel = pix;
406 else
408 vfbScreens[lastScreen].whitePixel = pix;
410 return 2;
413 if (strcmp (argv[i], "-linebias") == 0) /* -linebias n */
415 unsigned int linebias;
416 CHECK_FOR_REQUIRED_ARGUMENTS(1);
417 linebias = atoi(argv[++i]);
418 if (-1 == lastScreen)
420 int i;
421 for (i = 0; i < MAXSCREENS; i++)
423 vfbScreens[i].lineBias = linebias;
426 else
428 vfbScreens[lastScreen].lineBias = linebias;
430 return 2;
433 #ifdef HAS_MMAP
434 if (strcmp (argv[i], "-fbdir") == 0) /* -fbdir directory */
436 CHECK_FOR_REQUIRED_ARGUMENTS(1);
437 pfbdir = argv[++i];
438 fbmemtype = MMAPPED_FILE_FB;
439 return 2;
441 #endif /* HAS_MMAP */
443 #ifdef HAS_SHM
444 if (strcmp (argv[i], "-shmem") == 0) /* -shmem */
446 fbmemtype = SHARED_MEMORY_FB;
447 return 1;
449 #endif
451 return 0;
454 static ColormapPtr InstalledMaps[MAXSCREENS];
456 static int
457 vfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
459 /* By the time we are processing requests, we can guarantee that there
460 * is always a colormap installed */
461 *pmaps = InstalledMaps[pScreen->myNum]->mid;
462 return (1);
466 static void
467 vfbInstallColormap(ColormapPtr pmap)
469 int index = pmap->pScreen->myNum;
470 ColormapPtr oldpmap = InstalledMaps[index];
472 if (pmap != oldpmap)
474 int entries;
475 XWDFileHeader *pXWDHeader;
476 XWDColor *pXWDCmap;
477 VisualPtr pVisual;
478 Pixel * ppix;
479 xrgb * prgb;
480 xColorItem *defs;
481 int i;
483 if(oldpmap != (ColormapPtr)None)
484 WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
485 /* Install pmap */
486 InstalledMaps[index] = pmap;
487 WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
489 entries = pmap->pVisual->ColormapEntries;
490 pXWDHeader = vfbScreens[pmap->pScreen->myNum].pXWDHeader;
491 pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
492 pVisual = pmap->pVisual;
494 swapcopy32(pXWDHeader->visual_class, pVisual->class);
495 swapcopy32(pXWDHeader->red_mask, pVisual->redMask);
496 swapcopy32(pXWDHeader->green_mask, pVisual->greenMask);
497 swapcopy32(pXWDHeader->blue_mask, pVisual->blueMask);
498 swapcopy32(pXWDHeader->bits_per_rgb, pVisual->bitsPerRGBValue);
499 swapcopy32(pXWDHeader->colormap_entries, pVisual->ColormapEntries);
501 ppix = (Pixel *)ALLOCATE_LOCAL(entries * sizeof(Pixel));
502 prgb = (xrgb *)ALLOCATE_LOCAL(entries * sizeof(xrgb));
503 defs = (xColorItem *)ALLOCATE_LOCAL(entries * sizeof(xColorItem));
505 for (i = 0; i < entries; i++) ppix[i] = i;
506 /* XXX truecolor */
507 QueryColors(pmap, entries, ppix, prgb);
509 for (i = 0; i < entries; i++) { /* convert xrgbs to xColorItems */
510 defs[i].pixel = ppix[i] & 0xff; /* change pixel to index */
511 defs[i].red = prgb[i].red;
512 defs[i].green = prgb[i].green;
513 defs[i].blue = prgb[i].blue;
514 defs[i].flags = DoRed|DoGreen|DoBlue;
516 (*pmap->pScreen->StoreColors)(pmap, entries, defs);
518 DEALLOCATE_LOCAL(ppix);
519 DEALLOCATE_LOCAL(prgb);
520 DEALLOCATE_LOCAL(defs);
524 static void
525 vfbUninstallColormap(ColormapPtr pmap)
527 ColormapPtr curpmap = InstalledMaps[pmap->pScreen->myNum];
529 if(pmap == curpmap)
531 if (pmap->mid != pmap->pScreen->defColormap)
533 curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap,
534 RT_COLORMAP);
535 (*pmap->pScreen->InstallColormap)(curpmap);
540 static void
541 vfbStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs)
543 XWDColor *pXWDCmap;
544 int i;
546 if (pmap != InstalledMaps[pmap->pScreen->myNum])
548 return;
551 pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
553 if ((pmap->pVisual->class | DynamicClass) == DirectColor)
555 return;
558 for (i = 0; i < ndef; i++)
560 if (pdefs[i].flags & DoRed)
562 swapcopy16(pXWDCmap[pdefs[i].pixel].red, pdefs[i].red);
564 if (pdefs[i].flags & DoGreen)
566 swapcopy16(pXWDCmap[pdefs[i].pixel].green, pdefs[i].green);
568 if (pdefs[i].flags & DoBlue)
570 swapcopy16(pXWDCmap[pdefs[i].pixel].blue, pdefs[i].blue);
575 static Bool
576 vfbSaveScreen(ScreenPtr pScreen, int on)
578 return TRUE;
581 #ifdef HAS_MMAP
583 /* this flushes any changes to the screens out to the mmapped file */
584 static void
585 vfbBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadmask)
587 int i;
589 for (i = 0; i < vfbNumScreens; i++)
591 #ifdef MS_ASYNC
592 if (-1 == msync((caddr_t)vfbScreens[i].pXWDHeader,
593 (size_t)vfbScreens[i].sizeInBytes, MS_ASYNC))
594 #else
595 /* silly NetBSD and who else? */
596 if (-1 == msync((caddr_t)vfbScreens[i].pXWDHeader,
597 (size_t)vfbScreens[i].sizeInBytes))
598 #endif
600 perror("msync");
601 ErrorF("msync failed, errno %d", errno);
607 static void
608 vfbWakeupHandler(pointer blockData, int result, pointer pReadmask)
613 static void
614 vfbAllocateMmappedFramebuffer(vfbScreenInfoPtr pvfb)
616 #define DUMMY_BUFFER_SIZE 65536
617 char dummyBuffer[DUMMY_BUFFER_SIZE];
618 int currentFileSize, writeThisTime;
620 sprintf(pvfb->mmap_file, "%s/Xvfb_screen%d", pfbdir, pvfb->scrnum);
621 if (-1 == (pvfb->mmap_fd = open(pvfb->mmap_file, O_CREAT|O_RDWR, 0666)))
623 perror("open");
624 ErrorF("open %s failed, errno %d", pvfb->mmap_file, errno);
625 return;
628 /* Extend the file to be the proper size */
630 bzero(dummyBuffer, DUMMY_BUFFER_SIZE);
631 for (currentFileSize = 0;
632 currentFileSize < pvfb->sizeInBytes;
633 currentFileSize += writeThisTime)
635 writeThisTime = min(DUMMY_BUFFER_SIZE,
636 pvfb->sizeInBytes - currentFileSize);
637 if (-1 == write(pvfb->mmap_fd, dummyBuffer, writeThisTime))
639 perror("write");
640 ErrorF("write %s failed, errno %d", pvfb->mmap_file, errno);
641 return;
645 /* try to mmap the file */
647 pvfb->pXWDHeader = (XWDFileHeader *)mmap((caddr_t)NULL, pvfb->sizeInBytes,
648 PROT_READ|PROT_WRITE,
649 MAP_FILE|MAP_SHARED,
650 pvfb->mmap_fd, 0);
651 if (-1 == (long)pvfb->pXWDHeader)
653 perror("mmap");
654 ErrorF("mmap %s failed, errno %d", pvfb->mmap_file, errno);
655 pvfb->pXWDHeader = NULL;
656 return;
659 if (!RegisterBlockAndWakeupHandlers(vfbBlockHandler, vfbWakeupHandler,
660 NULL))
662 pvfb->pXWDHeader = NULL;
665 #endif /* HAS_MMAP */
668 #ifdef HAS_SHM
669 static void
670 vfbAllocateSharedMemoryFramebuffer(vfbScreenInfoPtr pvfb)
672 /* create the shared memory segment */
674 pvfb->shmid = shmget(IPC_PRIVATE, pvfb->sizeInBytes, IPC_CREAT|0777);
675 if (pvfb->shmid < 0)
677 perror("shmget");
678 ErrorF("shmget %d bytes failed, errno %d", pvfb->sizeInBytes, errno);
679 return;
682 /* try to attach it */
684 pvfb->pXWDHeader = (XWDFileHeader *)shmat(pvfb->shmid, 0, 0);
685 if (-1 == (long)pvfb->pXWDHeader)
687 perror("shmat");
688 ErrorF("shmat failed, errno %d", errno);
689 pvfb->pXWDHeader = NULL;
690 return;
693 ErrorF("screen %d shmid %d\n", pvfb->scrnum, pvfb->shmid);
695 #endif /* HAS_SHM */
697 static char *
698 vfbAllocateFramebufferMemory(vfbScreenInfoPtr pvfb)
700 if (pvfb->pfbMemory) return pvfb->pfbMemory; /* already done */
702 pvfb->sizeInBytes = pvfb->paddedBytesWidth * pvfb->height;
704 /* Calculate how many entries in colormap. This is rather bogus, because
705 * the visuals haven't even been set up yet, but we need to know because we
706 * have to allocate space in the file for the colormap. The number 10
707 * below comes from the MAX_PSEUDO_DEPTH define in cfbcmap.c.
710 if (pvfb->depth <= 10)
711 { /* single index colormaps */
712 pvfb->ncolors = 1 << pvfb->depth;
714 else
715 { /* decomposed colormaps */
716 int nplanes_per_color_component = pvfb->depth / 3;
717 if (pvfb->depth % 3) nplanes_per_color_component++;
718 pvfb->ncolors = 1 << nplanes_per_color_component;
721 /* add extra bytes for XWDFileHeader, window name, and colormap */
723 pvfb->sizeInBytes += SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN +
724 pvfb->ncolors * SIZEOF(XWDColor);
726 pvfb->pXWDHeader = NULL;
727 switch (fbmemtype)
729 #ifdef HAS_MMAP
730 case MMAPPED_FILE_FB: vfbAllocateMmappedFramebuffer(pvfb); break;
731 #else
732 case MMAPPED_FILE_FB: break;
733 #endif
735 #ifdef HAS_SHM
736 case SHARED_MEMORY_FB: vfbAllocateSharedMemoryFramebuffer(pvfb); break;
737 #else
738 case SHARED_MEMORY_FB: break;
739 #endif
741 case NORMAL_MEMORY_FB:
742 pvfb->pXWDHeader = (XWDFileHeader *)Xalloc(pvfb->sizeInBytes);
743 break;
746 if (pvfb->pXWDHeader)
748 pvfb->pXWDCmap = (XWDColor *)((char *)pvfb->pXWDHeader
749 + SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN);
750 pvfb->pfbMemory = (char *)(pvfb->pXWDCmap + pvfb->ncolors);
752 return pvfb->pfbMemory;
754 else
755 return NULL;
759 static void
760 vfbWriteXWDFileHeader(ScreenPtr pScreen)
762 vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
763 XWDFileHeader *pXWDHeader = pvfb->pXWDHeader;
764 char hostname[XWD_WINDOW_NAME_LEN];
765 unsigned long swaptest = 1;
766 int i;
768 needswap = *(char *) &swaptest;
770 pXWDHeader->header_size = (char *)pvfb->pXWDCmap - (char *)pvfb->pXWDHeader;
771 pXWDHeader->file_version = XWD_FILE_VERSION;
773 pXWDHeader->pixmap_format = ZPixmap;
774 pXWDHeader->pixmap_depth = pvfb->depth;
775 pXWDHeader->pixmap_height = pXWDHeader->window_height = pvfb->height;
776 pXWDHeader->xoffset = 0;
777 pXWDHeader->byte_order = IMAGE_BYTE_ORDER;
778 pXWDHeader->bitmap_bit_order = BITMAP_BIT_ORDER;
779 #ifndef INTERNAL_VS_EXTERNAL_PADDING
780 pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->width;
781 pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT;
782 pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD;
783 #else
784 pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->paddedWidth;
785 pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT_PROTO;
786 pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD_PROTO;
787 #endif
788 pXWDHeader->bits_per_pixel = pvfb->bitsPerPixel;
789 pXWDHeader->bytes_per_line = pvfb->paddedBytesWidth;
790 pXWDHeader->ncolors = pvfb->ncolors;
792 /* visual related fields are written when colormap is installed */
794 pXWDHeader->window_x = pXWDHeader->window_y = 0;
795 pXWDHeader->window_bdrwidth = 0;
797 /* write xwd "window" name: Xvfb hostname:server.screen */
799 if (-1 == gethostname(hostname, sizeof(hostname)))
800 hostname[0] = 0;
801 else
802 hostname[XWD_WINDOW_NAME_LEN-1] = 0;
803 sprintf((char *)(pXWDHeader+1), "Xvfb %s:%s.%d", hostname, display,
804 pScreen->myNum);
806 /* write colormap pixel slot values */
808 for (i = 0; i < pvfb->ncolors; i++)
810 pvfb->pXWDCmap[i].pixel = i;
813 /* byte swap to most significant byte first */
815 if (needswap)
817 SwapLongs((CARD32 *)pXWDHeader, SIZEOF(XWDheader)/4);
818 for (i = 0; i < pvfb->ncolors; i++)
820 register char n;
821 swapl(&pvfb->pXWDCmap[i].pixel, n);
827 static Bool
828 vfbCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y)
830 return FALSE;
833 static void
834 vfbCrossScreen (ScreenPtr pScreen, Bool entering)
838 static miPointerScreenFuncRec vfbPointerCursorFuncs =
840 vfbCursorOffScreen,
841 vfbCrossScreen,
842 miPointerWarpCursor
845 static Bool
846 vfbCloseScreen(int index, ScreenPtr pScreen)
848 vfbScreenInfoPtr pvfb = &vfbScreens[index];
849 int i;
851 pScreen->CloseScreen = pvfb->closeScreen;
854 * XXX probably lots of stuff to clean. For now,
855 * clear InstalledMaps[] so that server reset works correctly.
857 for (i = 0; i < MAXSCREENS; i++)
858 InstalledMaps[i] = NULL;
860 return pScreen->CloseScreen(index, pScreen);
863 static Bool
864 vfbScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
866 vfbScreenInfoPtr pvfb = &vfbScreens[index];
867 int dpix = monitorResolution, dpiy = monitorResolution;
868 int ret;
869 char *pbits;
871 if (dpix == 0)
872 dpix = 100;
874 if (dpiy == 0)
875 dpiy = 100;
877 pvfb->paddedBytesWidth = PixmapBytePad(pvfb->width, pvfb->depth);
878 pvfb->bitsPerPixel = vfbBitsPerPixel(pvfb->depth);
879 if (pvfb->bitsPerPixel >= 8 )
880 pvfb->paddedWidth = pvfb->paddedBytesWidth / (pvfb->bitsPerPixel / 8);
881 else
882 pvfb->paddedWidth = pvfb->paddedBytesWidth * 8;
883 pbits = vfbAllocateFramebufferMemory(pvfb);
884 if (!pbits) return FALSE;
886 miSetPixmapDepths ();
888 switch (pvfb->depth) {
889 case 8:
890 miSetVisualTypesAndMasks (8,
891 ((1 << StaticGray) |
892 (1 << GrayScale) |
893 (1 << StaticColor) |
894 (1 << PseudoColor) |
895 (1 << TrueColor) |
896 (1 << DirectColor)),
897 8, PseudoColor, 0, 0, 0);
898 break;
899 #if 0
900 /* 12bit PseudoColor with 12bit color resolution
901 * (to simulate SGI hardware and the 12bit PseudoColor emulation layer) */
902 case 12:
903 miSetVisualTypesAndMasks (12,
904 ((1 << StaticGray) |
905 (1 << GrayScale) |
906 (1 << StaticColor) |
907 (1 << PseudoColor) |
908 (1 << TrueColor) |
909 (1 << DirectColor)),
910 12, PseudoColor, 0, 0, 0);
911 break;
912 #endif
913 case 15:
914 miSetVisualTypesAndMasks (15,
915 ((1 << TrueColor) |
916 (1 << DirectColor)),
917 8, TrueColor, 0x7c00, 0x03e0, 0x001f);
918 break;
919 case 16:
920 miSetVisualTypesAndMasks (16,
921 ((1 << TrueColor) |
922 (1 << DirectColor)),
923 8, TrueColor, 0xf800, 0x07e0, 0x001f);
924 break;
925 case 24:
926 miSetVisualTypesAndMasks (24,
927 ((1 << TrueColor) |
928 (1 << DirectColor)),
929 8, TrueColor, 0xff0000, 0x00ff00, 0x0000ff);
930 break;
931 #if 0
932 /* 30bit TrueColor (to simulate Sun's XVR-1000/-4000 high quality
933 * framebuffer series) */
934 case 30:
935 miSetVisualTypesAndMasks (30,
936 ((1 << TrueColor) |
937 (1 << DirectColor)),
938 10, TrueColor, 0x3ff00000, 0x000ffc00, 0x000003ff);
939 break;
940 #endif
943 ret = fbScreenInit(pScreen, pbits, pvfb->width, pvfb->height,
944 dpix, dpiy, pvfb->paddedWidth,pvfb->bitsPerPixel);
945 #ifdef RENDER
946 if (ret && Render)
947 fbPictureInit (pScreen, 0, 0);
948 #endif
950 if (!ret) return FALSE;
952 miInitializeBackingStore(pScreen);
955 * Circumvent the backing store that was just initialised. This amounts
956 * to a truely bizarre way of initialising SaveDoomedAreas and friends.
959 pScreen->InstallColormap = vfbInstallColormap;
960 pScreen->UninstallColormap = vfbUninstallColormap;
961 pScreen->ListInstalledColormaps = vfbListInstalledColormaps;
963 pScreen->SaveScreen = vfbSaveScreen;
964 pScreen->StoreColors = vfbStoreColors;
966 miDCInitialize(pScreen, &vfbPointerCursorFuncs);
968 vfbWriteXWDFileHeader(pScreen);
970 pScreen->blackPixel = pvfb->blackPixel;
971 pScreen->whitePixel = pvfb->whitePixel;
973 ret = fbCreateDefColormap(pScreen);
975 miSetZeroLineBias(pScreen, pvfb->lineBias);
977 pvfb->closeScreen = pScreen->CloseScreen;
978 pScreen->CloseScreen = vfbCloseScreen;
980 return ret;
982 } /* end vfbScreenInit */
985 void
986 InitOutput(ScreenInfo *screenInfo, int argc, char **argv)
988 int i;
989 int NumFormats = 0;
991 /* initialize pixmap formats */
993 /* must have a pixmap depth to match every screen depth */
994 for (i = 0; i < vfbNumScreens; i++)
996 vfbPixmapDepths[vfbScreens[i].depth] = TRUE;
999 /* RENDER needs a good set of pixmaps. */
1000 if (Render) {
1001 vfbPixmapDepths[1] = TRUE;
1002 vfbPixmapDepths[4] = TRUE;
1003 vfbPixmapDepths[8] = TRUE;
1004 #if 0
1005 vfbPixmapDepths[12] = TRUE;
1006 #endif
1007 /* vfbPixmapDepths[15] = TRUE; */
1008 vfbPixmapDepths[16] = TRUE;
1009 vfbPixmapDepths[24] = TRUE;
1010 #if 0
1011 vfbPixmapDepths[30] = TRUE;
1012 #endif
1013 vfbPixmapDepths[32] = TRUE;
1016 for (i = 1; i <= 32; i++)
1018 if (vfbPixmapDepths[i])
1020 if (NumFormats >= MAXFORMATS)
1021 FatalError ("MAXFORMATS is too small for this server\n");
1022 screenInfo->formats[NumFormats].depth = i;
1023 screenInfo->formats[NumFormats].bitsPerPixel = vfbBitsPerPixel(i);
1024 screenInfo->formats[NumFormats].scanlinePad = BITMAP_SCANLINE_PAD;
1025 NumFormats++;
1029 screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
1030 screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
1031 screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
1032 screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
1033 screenInfo->numPixmapFormats = NumFormats;
1035 /* initialize screens */
1037 for (i = 0; i < vfbNumScreens; i++)
1039 if (-1 == AddScreen(vfbScreenInit, argc, argv))
1041 FatalError("Couldn't add screen %d", i);
1045 } /* end InitOutput */
1047 /* this is just to get the server to link on AIX */
1048 #ifdef AIXV3
1049 int SelectWaitTime = 10000; /* usec */
1050 #endif