~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to hw/vfb/InitOutput.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Xorg: InitOutput.c,v 1.4 2001/02/09 02:04:45 xorgcvs Exp $ */
 
2
/*
 
3
 
 
4
Copyright 1993, 1998  The Open Group
 
5
 
 
6
Permission to use, copy, modify, distribute, and sell this software and its
 
7
documentation for any purpose is hereby granted without fee, provided that
 
8
the above copyright notice appear in all copies and that both that
 
9
copyright notice and this permission notice appear in supporting
 
10
documentation.
 
11
 
 
12
The above copyright notice and this permission notice shall be included
 
13
in all copies or substantial portions of the Software.
 
14
 
 
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
16
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
17
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 
18
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
 
19
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 
20
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 
21
OTHER DEALINGS IN THE SOFTWARE.
 
22
 
 
23
Except as contained in this notice, the name of The Open Group shall
 
24
not be used in advertising or otherwise to promote the sale, use or
 
25
other dealings in this Software without prior written authorization
 
26
from The Open Group.
 
27
 
 
28
*/
 
29
/* $XFree86: xc/programs/Xserver/hw/vfb/InitOutput.c,v 3.25 2003/11/15 04:01:56 dawes Exp $ */
 
30
 
 
31
#ifdef HAVE_DIX_CONFIG_H
 
32
#include <dix-config.h>
 
33
#endif
 
34
 
 
35
#if defined(WIN32)
 
36
#include <X11/Xwinsock.h>
 
37
#endif
 
38
#include <stdio.h>
 
39
#include <X11/X.h>
 
40
#define NEED_EVENTS
 
41
#include <X11/Xproto.h>
 
42
#include <X11/Xos.h>
 
43
#include "scrnintstr.h"
 
44
#include "servermd.h"
 
45
#define PSZ 8
 
46
#include "fb.h"
 
47
#include "mibstore.h"
 
48
#include "colormapst.h"
 
49
#include "gcstruct.h"
 
50
#include "input.h"
 
51
#include "mipointer.h"
 
52
#include "micmap.h"
 
53
#include <sys/types.h>
 
54
#ifdef HAS_MMAP
 
55
#include <sys/mman.h>
 
56
#ifndef MAP_FILE
 
57
#define MAP_FILE 0
 
58
#endif
 
59
#endif /* HAS_MMAP */
 
60
#include <sys/stat.h>
 
61
#include <errno.h>
 
62
#ifndef WIN32
 
63
#include <sys/param.h>
 
64
#endif
 
65
#include <X11/XWDFile.h>
 
66
#ifdef HAS_SHM
 
67
#include <sys/ipc.h>
 
68
#include <sys/shm.h>
 
69
#endif /* HAS_SHM */
 
70
#include "dix.h"
 
71
#include "miline.h"
 
72
 
 
73
#define VFB_DEFAULT_WIDTH      1280
 
74
#define VFB_DEFAULT_HEIGHT     1024
 
75
#define VFB_DEFAULT_DEPTH         8
 
76
#define VFB_DEFAULT_WHITEPIXEL    1
 
77
#define VFB_DEFAULT_BLACKPIXEL    0
 
78
#define VFB_DEFAULT_LINEBIAS      0
 
79
#define XWD_WINDOW_NAME_LEN      60
 
80
 
 
81
typedef struct
 
82
{
 
83
    int scrnum;
 
84
    int width;
 
85
    int paddedBytesWidth;
 
86
    int paddedWidth;
 
87
    int height;
 
88
    int depth;
 
89
    int bitsPerPixel;
 
90
    int sizeInBytes;
 
91
    int ncolors;
 
92
    char *pfbMemory;
 
93
    XWDColor *pXWDCmap;
 
94
    XWDFileHeader *pXWDHeader;
 
95
    Pixel blackPixel;
 
96
    Pixel whitePixel;
 
97
    unsigned int lineBias;
 
98
    CloseScreenProcPtr closeScreen;
 
99
 
 
100
#ifdef HAS_MMAP
 
101
    int mmap_fd;
 
102
    char mmap_file[MAXPATHLEN];
 
103
#endif
 
104
 
 
105
#ifdef HAS_SHM
 
106
    int shmid;
 
107
#endif
 
108
} vfbScreenInfo, *vfbScreenInfoPtr;
 
109
 
 
110
static int vfbNumScreens;
 
111
static vfbScreenInfo vfbScreens[MAXSCREENS];
 
112
static Bool vfbPixmapDepths[33];
 
113
#ifdef HAS_MMAP
 
114
static char *pfbdir = NULL;
 
115
#endif
 
116
typedef enum { NORMAL_MEMORY_FB, SHARED_MEMORY_FB, MMAPPED_FILE_FB } fbMemType;
 
117
static fbMemType fbmemtype = NORMAL_MEMORY_FB;
 
118
static char needswap = 0;
 
119
static int lastScreen = -1;
 
120
static Bool Render = TRUE;
 
121
 
 
122
#define swapcopy16(_dst, _src) \
 
123
    if (needswap) { CARD16 _s = _src; cpswaps(_s, _dst); } \
 
124
    else _dst = _src;
 
125
 
 
126
#define swapcopy32(_dst, _src) \
 
127
    if (needswap) { CARD32 _s = _src; cpswapl(_s, _dst); } \
 
128
    else _dst = _src;
 
129
 
 
130
 
 
131
static void
 
132
vfbInitializePixmapDepths(void)
 
133
{
 
134
    int i;
 
135
    vfbPixmapDepths[1] = TRUE; /* always need bitmaps */
 
136
    for (i = 2; i <= 32; i++)
 
137
        vfbPixmapDepths[i] = FALSE;
 
138
}
 
139
 
 
140
static void
 
141
vfbInitializeDefaultScreens(void)
 
142
{
 
143
    int i;
 
144
 
 
145
    for (i = 0; i < MAXSCREENS; i++)
 
146
    {
 
147
        vfbScreens[i].scrnum = i;
 
148
        vfbScreens[i].width  = VFB_DEFAULT_WIDTH;
 
149
        vfbScreens[i].height = VFB_DEFAULT_HEIGHT;
 
150
        vfbScreens[i].depth  = VFB_DEFAULT_DEPTH;
 
151
        vfbScreens[i].blackPixel = VFB_DEFAULT_BLACKPIXEL;
 
152
        vfbScreens[i].whitePixel = VFB_DEFAULT_WHITEPIXEL;
 
153
        vfbScreens[i].lineBias = VFB_DEFAULT_LINEBIAS;
 
154
        vfbScreens[i].pfbMemory = NULL;
 
155
    }
 
156
    vfbNumScreens = 1;
 
157
}
 
158
 
 
159
static int
 
160
vfbBitsPerPixel(int depth)
 
161
{
 
162
    if (depth == 1) return 1;
 
163
    else if (depth <= 8) return 8;
 
164
    else if (depth <= 16) return 16;
 
165
    else return 32;
 
166
}
 
167
 
 
168
void
 
169
ddxGiveUp()
 
170
{
 
171
    int i;
 
172
 
 
173
    /* clean up the framebuffers */
 
174
 
 
175
    switch (fbmemtype)
 
176
    {
 
177
#ifdef HAS_MMAP
 
178
    case MMAPPED_FILE_FB: 
 
179
        for (i = 0; i < vfbNumScreens; i++)
 
180
        {
 
181
            if (-1 == unlink(vfbScreens[i].mmap_file))
 
182
            {
 
183
                perror("unlink");
 
184
                ErrorF("unlink %s failed, errno %d",
 
185
                       vfbScreens[i].mmap_file, errno);
 
186
            }
 
187
        }
 
188
        break;
 
189
#else /* HAS_MMAP */
 
190
    case MMAPPED_FILE_FB:
 
191
        break;
 
192
#endif /* HAS_MMAP */
 
193
        
 
194
#ifdef HAS_SHM
 
195
    case SHARED_MEMORY_FB:
 
196
        for (i = 0; i < vfbNumScreens; i++)
 
197
        {
 
198
            if (-1 == shmdt((char *)vfbScreens[i].pXWDHeader))
 
199
            {
 
200
                perror("shmdt");
 
201
                ErrorF("shmdt failed, errno %d", errno);
 
202
            }
 
203
        }
 
204
        break;
 
205
#else /* HAS_SHM */
 
206
    case SHARED_MEMORY_FB:
 
207
        break;
 
208
#endif /* HAS_SHM */
 
209
        
 
210
    case NORMAL_MEMORY_FB:
 
211
        for (i = 0; i < vfbNumScreens; i++)
 
212
        {
 
213
            Xfree(vfbScreens[i].pXWDHeader);
 
214
        }
 
215
        break;
 
216
    }
 
217
}
 
218
 
 
219
void
 
220
AbortDDX()
 
221
{
 
222
    ddxGiveUp();
 
223
}
 
224
 
 
225
#ifdef __DARWIN__
 
226
void
 
227
DarwinHandleGUI(int argc, char *argv[])
 
228
{
 
229
}
 
230
 
 
231
void GlxExtensionInit();
 
232
void GlxWrapInitVisuals(void *procPtr);
 
233
 
 
234
void
 
235
DarwinGlxExtensionInit()
 
236
{
 
237
    GlxExtensionInit();
 
238
}
 
239
 
 
240
void
 
241
DarwinGlxWrapInitVisuals(
 
242
    void *procPtr)
 
243
{
 
244
    GlxWrapInitVisuals(procPtr);
 
245
}
 
246
#endif
 
247
 
 
248
void
 
249
OsVendorInit()
 
250
{
 
251
}
 
252
 
 
253
void
 
254
OsVendorFatalError()
 
255
{
 
256
}
 
257
 
 
258
void ddxBeforeReset(void)
 
259
{
 
260
    return;
 
261
}
 
262
 
 
263
void
 
264
ddxUseMsg()
 
265
{
 
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");
 
275
 
 
276
#ifdef HAS_MMAP
 
277
    ErrorF("-fbdir directory       put framebuffers in mmap'ed files in directory\n");
 
278
#endif
 
279
 
 
280
#ifdef HAS_SHM
 
281
    ErrorF("-shmem                 put framebuffers in shared memory\n");
 
282
#endif
 
283
}
 
284
 
 
285
/* ddxInitGlobals - called by |InitGlobals| from os/util.c */
 
286
void ddxInitGlobals(void)
 
287
{
 
288
}
 
289
 
 
290
int
 
291
ddxProcessArgument(int argc, char *argv[], int i)
 
292
{
 
293
    static Bool firstTime = TRUE;
 
294
 
 
295
    if (firstTime)
 
296
    {
 
297
        vfbInitializeDefaultScreens();
 
298
        vfbInitializePixmapDepths();
 
299
        firstTime = FALSE;
 
300
    }
 
301
 
 
302
    if (strcmp (argv[i], "-screen") == 0)       /* -screen n WxHxD */
 
303
    {
 
304
        int screenNum;
 
305
        if (i + 2 >= argc) UseMsg();
 
306
        screenNum = atoi(argv[i+1]);
 
307
        if (screenNum < 0 || screenNum >= MAXSCREENS)
 
308
        {
 
309
            ErrorF("Invalid screen number %d\n", screenNum);
 
310
            UseMsg();
 
311
        }
 
312
        if (3 != sscanf(argv[i+2], "%dx%dx%d",
 
313
                        &vfbScreens[screenNum].width,
 
314
                        &vfbScreens[screenNum].height,
 
315
                        &vfbScreens[screenNum].depth))
 
316
        {
 
317
            ErrorF("Invalid screen configuration %s\n", argv[i+2]);
 
318
            UseMsg();
 
319
        }
 
320
 
 
321
        if (screenNum >= vfbNumScreens)
 
322
            vfbNumScreens = screenNum + 1;
 
323
        lastScreen = screenNum;
 
324
        return 3;
 
325
    }
 
326
 
 
327
    if (strcmp (argv[i], "-pixdepths") == 0)    /* -pixdepths list-of-depth */
 
328
    {
 
329
        int depth, ret = 1;
 
330
 
 
331
        if (++i >= argc) UseMsg();
 
332
        while ((i < argc) && (depth = atoi(argv[i++])) != 0)
 
333
        {
 
334
            if (depth < 0 || depth > 32)
 
335
            {
 
336
                ErrorF("Invalid pixmap depth %d\n", depth);
 
337
                UseMsg();
 
338
            }
 
339
            vfbPixmapDepths[depth] = TRUE;
 
340
            ret++;
 
341
        }
 
342
        return ret;
 
343
    }
 
344
 
 
345
    if (strcmp (argv[i], "+render") == 0)       /* +render */
 
346
    {
 
347
        Render = TRUE;
 
348
        return 1;
 
349
    }
 
350
 
 
351
    if (strcmp (argv[i], "-render") == 0)       /* -render */
 
352
    {
 
353
        Render = FALSE;
 
354
        return 1;
 
355
    }
 
356
 
 
357
    if (strcmp (argv[i], "-blackpixel") == 0)   /* -blackpixel n */
 
358
    {
 
359
        Pixel pix;
 
360
        if (++i >= argc) UseMsg();
 
361
        pix = atoi(argv[i]);
 
362
        if (-1 == lastScreen)
 
363
        {
 
364
            int i;
 
365
            for (i = 0; i < MAXSCREENS; i++)
 
366
            {
 
367
                vfbScreens[i].blackPixel = pix;
 
368
            }
 
369
        }
 
370
        else
 
371
        {
 
372
            vfbScreens[lastScreen].blackPixel = pix;
 
373
        }
 
374
        return 2;
 
375
    }
 
376
 
 
377
    if (strcmp (argv[i], "-whitepixel") == 0)   /* -whitepixel n */
 
378
    {
 
379
        Pixel pix;
 
380
        if (++i >= argc) UseMsg();
 
381
        pix = atoi(argv[i]);
 
382
        if (-1 == lastScreen)
 
383
        {
 
384
            int i;
 
385
            for (i = 0; i < MAXSCREENS; i++)
 
386
            {
 
387
                vfbScreens[i].whitePixel = pix;
 
388
            }
 
389
        }
 
390
        else
 
391
        {
 
392
            vfbScreens[lastScreen].whitePixel = pix;
 
393
        }
 
394
        return 2;
 
395
    }
 
396
 
 
397
    if (strcmp (argv[i], "-linebias") == 0)     /* -linebias n */
 
398
    {
 
399
        unsigned int linebias;
 
400
        if (++i >= argc) UseMsg();
 
401
        linebias = atoi(argv[i]);
 
402
        if (-1 == lastScreen)
 
403
        {
 
404
            int i;
 
405
            for (i = 0; i < MAXSCREENS; i++)
 
406
            {
 
407
                vfbScreens[i].lineBias = linebias;
 
408
            }
 
409
        }
 
410
        else
 
411
        {
 
412
            vfbScreens[lastScreen].lineBias = linebias;
 
413
        }
 
414
        return 2;
 
415
    }
 
416
 
 
417
#ifdef HAS_MMAP
 
418
    if (strcmp (argv[i], "-fbdir") == 0)        /* -fbdir directory */
 
419
    {
 
420
        if (++i >= argc) UseMsg();
 
421
        pfbdir = argv[i];
 
422
        fbmemtype = MMAPPED_FILE_FB;
 
423
        return 2;
 
424
    }
 
425
#endif /* HAS_MMAP */
 
426
 
 
427
#ifdef HAS_SHM
 
428
    if (strcmp (argv[i], "-shmem") == 0)        /* -shmem */
 
429
    {
 
430
        fbmemtype = SHARED_MEMORY_FB;
 
431
        return 1;
 
432
    }
 
433
#endif
 
434
 
 
435
    return 0;
 
436
}
 
437
 
 
438
#ifdef DDXTIME /* from ServerOSDefines */
 
439
CARD32
 
440
GetTimeInMillis()
 
441
{
 
442
    struct timeval  tp;
 
443
 
 
444
    X_GETTIMEOFDAY(&tp);
 
445
    return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
 
446
}
 
447
#endif
 
448
 
 
449
static ColormapPtr InstalledMaps[MAXSCREENS];
 
450
 
 
451
static int
 
452
vfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
 
453
{
 
454
    /* By the time we are processing requests, we can guarantee that there
 
455
     * is always a colormap installed */
 
456
    *pmaps = InstalledMaps[pScreen->myNum]->mid;
 
457
    return (1);
 
458
}
 
459
 
 
460
 
 
461
static void
 
462
vfbInstallColormap(ColormapPtr pmap)
 
463
{
 
464
    int index = pmap->pScreen->myNum;
 
465
    ColormapPtr oldpmap = InstalledMaps[index];
 
466
 
 
467
    if (pmap != oldpmap)
 
468
    {
 
469
        int entries;
 
470
        XWDFileHeader *pXWDHeader;
 
471
        XWDColor *pXWDCmap;
 
472
        VisualPtr pVisual;
 
473
        Pixel *     ppix;
 
474
        xrgb *      prgb;
 
475
        xColorItem *defs;
 
476
        int i;
 
477
 
 
478
        if(oldpmap != (ColormapPtr)None)
 
479
            WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
 
480
        /* Install pmap */
 
481
        InstalledMaps[index] = pmap;
 
482
        WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
 
483
 
 
484
        entries = pmap->pVisual->ColormapEntries;
 
485
        pXWDHeader = vfbScreens[pmap->pScreen->myNum].pXWDHeader;
 
486
        pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
 
487
        pVisual = pmap->pVisual;
 
488
 
 
489
        swapcopy32(pXWDHeader->visual_class, pVisual->class);
 
490
        swapcopy32(pXWDHeader->red_mask, pVisual->redMask);
 
491
        swapcopy32(pXWDHeader->green_mask, pVisual->greenMask);
 
492
        swapcopy32(pXWDHeader->blue_mask, pVisual->blueMask);
 
493
        swapcopy32(pXWDHeader->bits_per_rgb, pVisual->bitsPerRGBValue);
 
494
        swapcopy32(pXWDHeader->colormap_entries, pVisual->ColormapEntries);
 
495
 
 
496
        ppix = (Pixel *)ALLOCATE_LOCAL(entries * sizeof(Pixel));
 
497
        prgb = (xrgb *)ALLOCATE_LOCAL(entries * sizeof(xrgb));
 
498
        defs = (xColorItem *)ALLOCATE_LOCAL(entries * sizeof(xColorItem));
 
499
 
 
500
        for (i = 0; i < entries; i++)  ppix[i] = i;
 
501
        /* XXX truecolor */
 
502
        QueryColors(pmap, entries, ppix, prgb);
 
503
 
 
504
        for (i = 0; i < entries; i++) { /* convert xrgbs to xColorItems */
 
505
            defs[i].pixel = ppix[i] & 0xff; /* change pixel to index */
 
506
            defs[i].red = prgb[i].red;
 
507
            defs[i].green = prgb[i].green;
 
508
            defs[i].blue = prgb[i].blue;
 
509
            defs[i].flags =  DoRed|DoGreen|DoBlue;
 
510
        }
 
511
        (*pmap->pScreen->StoreColors)(pmap, entries, defs);
 
512
 
 
513
        DEALLOCATE_LOCAL(ppix);
 
514
        DEALLOCATE_LOCAL(prgb);
 
515
        DEALLOCATE_LOCAL(defs);
 
516
    }
 
517
}
 
518
 
 
519
static void
 
520
vfbUninstallColormap(ColormapPtr pmap)
 
521
{
 
522
    ColormapPtr curpmap = InstalledMaps[pmap->pScreen->myNum];
 
523
 
 
524
    if(pmap == curpmap)
 
525
    {
 
526
        if (pmap->mid != pmap->pScreen->defColormap)
 
527
        {
 
528
            curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap,
 
529
                                                   RT_COLORMAP);
 
530
            (*pmap->pScreen->InstallColormap)(curpmap);
 
531
        }
 
532
    }
 
533
}
 
534
 
 
535
static void
 
536
vfbStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs)
 
537
{
 
538
    XWDColor *pXWDCmap;
 
539
    int i;
 
540
 
 
541
    if (pmap != InstalledMaps[pmap->pScreen->myNum])
 
542
    {
 
543
        return;
 
544
    }
 
545
 
 
546
    pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
 
547
 
 
548
    if ((pmap->pVisual->class | DynamicClass) == DirectColor)
 
549
    {
 
550
        return;
 
551
    }
 
552
 
 
553
    for (i = 0; i < ndef; i++)
 
554
    {
 
555
        if (pdefs[i].flags & DoRed)
 
556
        {
 
557
            swapcopy16(pXWDCmap[pdefs[i].pixel].red, pdefs[i].red);
 
558
        }
 
559
        if (pdefs[i].flags & DoGreen)
 
560
        {
 
561
            swapcopy16(pXWDCmap[pdefs[i].pixel].green, pdefs[i].green);
 
562
        }
 
563
        if (pdefs[i].flags & DoBlue)
 
564
        {
 
565
            swapcopy16(pXWDCmap[pdefs[i].pixel].blue, pdefs[i].blue);
 
566
        }
 
567
    }
 
568
}
 
569
 
 
570
static Bool
 
571
vfbSaveScreen(ScreenPtr pScreen, int on)
 
572
{
 
573
    return TRUE;
 
574
}
 
575
 
 
576
#ifdef HAS_MMAP
 
577
 
 
578
/* this flushes any changes to the screens out to the mmapped file */
 
579
static void
 
580
vfbBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadmask)
 
581
{
 
582
    int i;
 
583
 
 
584
    for (i = 0; i < vfbNumScreens; i++)
 
585
    {
 
586
#ifdef MS_ASYNC
 
587
        if (-1 == msync((caddr_t)vfbScreens[i].pXWDHeader,
 
588
                        (size_t)vfbScreens[i].sizeInBytes, MS_ASYNC))
 
589
#else
 
590
        /* silly NetBSD and who else? */
 
591
        if (-1 == msync((caddr_t)vfbScreens[i].pXWDHeader,
 
592
                        (size_t)vfbScreens[i].sizeInBytes))
 
593
#endif
 
594
        {
 
595
            perror("msync");
 
596
            ErrorF("msync failed, errno %d", errno);
 
597
        }
 
598
    }
 
599
}
 
600
 
 
601
 
 
602
static void
 
603
vfbWakeupHandler(pointer blockData, int result, pointer pReadmask)
 
604
{
 
605
}
 
606
 
 
607
 
 
608
static void
 
609
vfbAllocateMmappedFramebuffer(vfbScreenInfoPtr pvfb)
 
610
{
 
611
#define DUMMY_BUFFER_SIZE 65536
 
612
    char dummyBuffer[DUMMY_BUFFER_SIZE];
 
613
    int currentFileSize, writeThisTime;
 
614
 
 
615
    sprintf(pvfb->mmap_file, "%s/Xvfb_screen%d", pfbdir, pvfb->scrnum);
 
616
    if (-1 == (pvfb->mmap_fd = open(pvfb->mmap_file, O_CREAT|O_RDWR, 0666)))
 
617
    {
 
618
        perror("open");
 
619
        ErrorF("open %s failed, errno %d", pvfb->mmap_file, errno);
 
620
        return;
 
621
    }
 
622
 
 
623
    /* Extend the file to be the proper size */
 
624
 
 
625
    bzero(dummyBuffer, DUMMY_BUFFER_SIZE);
 
626
    for (currentFileSize = 0;
 
627
         currentFileSize < pvfb->sizeInBytes;
 
628
         currentFileSize += writeThisTime)
 
629
    {
 
630
        writeThisTime = min(DUMMY_BUFFER_SIZE,
 
631
                            pvfb->sizeInBytes - currentFileSize);
 
632
        if (-1 == write(pvfb->mmap_fd, dummyBuffer, writeThisTime))
 
633
        {
 
634
            perror("write");
 
635
            ErrorF("write %s failed, errno %d", pvfb->mmap_file, errno);
 
636
            return;
 
637
        }
 
638
    }
 
639
 
 
640
    /* try to mmap the file */
 
641
 
 
642
    pvfb->pXWDHeader = (XWDFileHeader *)mmap((caddr_t)NULL, pvfb->sizeInBytes,
 
643
                                    PROT_READ|PROT_WRITE,
 
644
                                    MAP_FILE|MAP_SHARED,
 
645
                                    pvfb->mmap_fd, 0);
 
646
    if (-1 == (long)pvfb->pXWDHeader)
 
647
    {
 
648
        perror("mmap");
 
649
        ErrorF("mmap %s failed, errno %d", pvfb->mmap_file, errno);
 
650
        pvfb->pXWDHeader = NULL;
 
651
        return;
 
652
    }
 
653
 
 
654
    if (!RegisterBlockAndWakeupHandlers(vfbBlockHandler, vfbWakeupHandler,
 
655
                                        NULL))
 
656
    {
 
657
        pvfb->pXWDHeader = NULL;
 
658
    }
 
659
}
 
660
#endif /* HAS_MMAP */
 
661
 
 
662
 
 
663
#ifdef HAS_SHM
 
664
static void
 
665
vfbAllocateSharedMemoryFramebuffer(vfbScreenInfoPtr pvfb)
 
666
{
 
667
    /* create the shared memory segment */
 
668
 
 
669
    pvfb->shmid = shmget(IPC_PRIVATE, pvfb->sizeInBytes, IPC_CREAT|0777);
 
670
    if (pvfb->shmid < 0)
 
671
    {
 
672
        perror("shmget");
 
673
        ErrorF("shmget %d bytes failed, errno %d", pvfb->sizeInBytes, errno);
 
674
        return;
 
675
    }
 
676
 
 
677
    /* try to attach it */
 
678
 
 
679
    pvfb->pXWDHeader = (XWDFileHeader *)shmat(pvfb->shmid, 0, 0);
 
680
    if (-1 == (long)pvfb->pXWDHeader)
 
681
    {
 
682
        perror("shmat");
 
683
        ErrorF("shmat failed, errno %d", errno);
 
684
        pvfb->pXWDHeader = NULL; 
 
685
        return;
 
686
    }
 
687
 
 
688
    ErrorF("screen %d shmid %d\n", pvfb->scrnum, pvfb->shmid);
 
689
}
 
690
#endif /* HAS_SHM */
 
691
 
 
692
static char *
 
693
vfbAllocateFramebufferMemory(vfbScreenInfoPtr pvfb)
 
694
{
 
695
    if (pvfb->pfbMemory) return pvfb->pfbMemory; /* already done */
 
696
 
 
697
    pvfb->sizeInBytes = pvfb->paddedBytesWidth * pvfb->height;
 
698
 
 
699
    /* Calculate how many entries in colormap.  This is rather bogus, because
 
700
     * the visuals haven't even been set up yet, but we need to know because we
 
701
     * have to allocate space in the file for the colormap.  The number 10
 
702
     * below comes from the MAX_PSEUDO_DEPTH define in cfbcmap.c.
 
703
     */
 
704
 
 
705
    if (pvfb->depth <= 10)
 
706
    { /* single index colormaps */
 
707
        pvfb->ncolors = 1 << pvfb->depth;
 
708
    }
 
709
    else
 
710
    { /* decomposed colormaps */
 
711
        int nplanes_per_color_component = pvfb->depth / 3;
 
712
        if (pvfb->depth % 3) nplanes_per_color_component++;
 
713
        pvfb->ncolors = 1 << nplanes_per_color_component;
 
714
    }
 
715
 
 
716
    /* add extra bytes for XWDFileHeader, window name, and colormap */
 
717
 
 
718
    pvfb->sizeInBytes += SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN +
 
719
                    pvfb->ncolors * SIZEOF(XWDColor);
 
720
 
 
721
    pvfb->pXWDHeader = NULL; 
 
722
    switch (fbmemtype)
 
723
    {
 
724
#ifdef HAS_MMAP
 
725
    case MMAPPED_FILE_FB:  vfbAllocateMmappedFramebuffer(pvfb); break;
 
726
#else
 
727
    case MMAPPED_FILE_FB: break;
 
728
#endif
 
729
 
 
730
#ifdef HAS_SHM
 
731
    case SHARED_MEMORY_FB: vfbAllocateSharedMemoryFramebuffer(pvfb); break;
 
732
#else
 
733
    case SHARED_MEMORY_FB: break;
 
734
#endif
 
735
 
 
736
    case NORMAL_MEMORY_FB:
 
737
        pvfb->pXWDHeader = (XWDFileHeader *)Xalloc(pvfb->sizeInBytes);
 
738
        break;
 
739
    }
 
740
 
 
741
    if (pvfb->pXWDHeader)
 
742
    {
 
743
        pvfb->pXWDCmap = (XWDColor *)((char *)pvfb->pXWDHeader
 
744
                                + SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN);
 
745
        pvfb->pfbMemory = (char *)(pvfb->pXWDCmap + pvfb->ncolors);
 
746
 
 
747
        return pvfb->pfbMemory;
 
748
    }
 
749
    else
 
750
        return NULL;
 
751
}
 
752
 
 
753
 
 
754
static void
 
755
vfbWriteXWDFileHeader(ScreenPtr pScreen)
 
756
{
 
757
    vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
 
758
    XWDFileHeader *pXWDHeader = pvfb->pXWDHeader;
 
759
    char hostname[XWD_WINDOW_NAME_LEN];
 
760
    unsigned long swaptest = 1;
 
761
    int i;
 
762
 
 
763
    needswap = *(char *) &swaptest;
 
764
 
 
765
    pXWDHeader->header_size = (char *)pvfb->pXWDCmap - (char *)pvfb->pXWDHeader;
 
766
    pXWDHeader->file_version = XWD_FILE_VERSION;
 
767
 
 
768
    pXWDHeader->pixmap_format = ZPixmap;
 
769
    pXWDHeader->pixmap_depth = pvfb->depth;
 
770
    pXWDHeader->pixmap_height = pXWDHeader->window_height = pvfb->height;
 
771
    pXWDHeader->xoffset = 0;
 
772
    pXWDHeader->byte_order = IMAGE_BYTE_ORDER;
 
773
    pXWDHeader->bitmap_bit_order = BITMAP_BIT_ORDER;
 
774
#ifndef INTERNAL_VS_EXTERNAL_PADDING
 
775
    pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->width;
 
776
    pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT;
 
777
    pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD;
 
778
#else
 
779
    pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->paddedWidth;
 
780
    pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT_PROTO;
 
781
    pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD_PROTO;
 
782
#endif
 
783
    pXWDHeader->bits_per_pixel = pvfb->bitsPerPixel;
 
784
    pXWDHeader->bytes_per_line = pvfb->paddedBytesWidth;
 
785
    pXWDHeader->ncolors = pvfb->ncolors;
 
786
 
 
787
    /* visual related fields are written when colormap is installed */
 
788
 
 
789
    pXWDHeader->window_x = pXWDHeader->window_y = 0;
 
790
    pXWDHeader->window_bdrwidth = 0;
 
791
 
 
792
    /* write xwd "window" name: Xvfb hostname:server.screen */
 
793
 
 
794
    if (-1 == gethostname(hostname, sizeof(hostname)))
 
795
        hostname[0] = 0;
 
796
    else
 
797
        hostname[XWD_WINDOW_NAME_LEN-1] = 0;
 
798
    sprintf((char *)(pXWDHeader+1), "Xvfb %s:%s.%d", hostname, display,
 
799
            pScreen->myNum);
 
800
 
 
801
    /* write colormap pixel slot values */
 
802
 
 
803
    for (i = 0; i < pvfb->ncolors; i++)
 
804
    {
 
805
        pvfb->pXWDCmap[i].pixel = i;
 
806
    }
 
807
 
 
808
    /* byte swap to most significant byte first */
 
809
 
 
810
    if (needswap)
 
811
    {
 
812
        SwapLongs((CARD32 *)pXWDHeader, SIZEOF(XWDheader)/4);
 
813
        for (i = 0; i < pvfb->ncolors; i++)
 
814
        {
 
815
            register char n;
 
816
            swapl(&pvfb->pXWDCmap[i].pixel, n);
 
817
        }
 
818
    }
 
819
}
 
820
 
 
821
 
 
822
static Bool
 
823
vfbCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y)
 
824
{
 
825
    return FALSE;
 
826
}
 
827
 
 
828
static void
 
829
vfbCrossScreen (ScreenPtr pScreen, Bool entering)
 
830
{
 
831
}
 
832
 
 
833
static miPointerScreenFuncRec vfbPointerCursorFuncs =
 
834
{
 
835
    vfbCursorOffScreen,
 
836
    vfbCrossScreen,
 
837
    miPointerWarpCursor
 
838
};
 
839
 
 
840
static Bool
 
841
vfbCloseScreen(int index, ScreenPtr pScreen)
 
842
{
 
843
    vfbScreenInfoPtr pvfb = &vfbScreens[index];
 
844
    int i;
 
845
 
 
846
    pScreen->CloseScreen = pvfb->closeScreen;
 
847
 
 
848
    /*
 
849
     * XXX probably lots of stuff to clean.  For now,
 
850
     * clear InstalledMaps[] so that server reset works correctly.
 
851
     */
 
852
    for (i = 0; i < MAXSCREENS; i++)
 
853
        InstalledMaps[i] = NULL;
 
854
 
 
855
    return pScreen->CloseScreen(index, pScreen);
 
856
}
 
857
 
 
858
static Bool
 
859
vfbScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
 
860
{
 
861
    vfbScreenInfoPtr pvfb = &vfbScreens[index];
 
862
    int dpix = monitorResolution, dpiy = monitorResolution;
 
863
    int ret;
 
864
    char *pbits;
 
865
    
 
866
    if (dpix == 0)
 
867
      dpix = 100;
 
868
 
 
869
    if (dpiy == 0)
 
870
      dpiy = 100;
 
871
 
 
872
    pvfb->paddedBytesWidth = PixmapBytePad(pvfb->width, pvfb->depth);
 
873
    pvfb->bitsPerPixel = vfbBitsPerPixel(pvfb->depth);
 
874
    if (pvfb->bitsPerPixel >= 8 )
 
875
        pvfb->paddedWidth = pvfb->paddedBytesWidth / (pvfb->bitsPerPixel / 8);
 
876
    else
 
877
        pvfb->paddedWidth = pvfb->paddedBytesWidth * 8;
 
878
    pbits = vfbAllocateFramebufferMemory(pvfb);
 
879
    if (!pbits) return FALSE;
 
880
 
 
881
    miSetPixmapDepths ();
 
882
 
 
883
    switch (pvfb->depth) {
 
884
    case 8:
 
885
        miSetVisualTypesAndMasks (8,
 
886
                                  ((1 << StaticGray) |
 
887
                                   (1 << GrayScale) |
 
888
                                   (1 << StaticColor) |
 
889
                                   (1 << PseudoColor) |
 
890
                                   (1 << TrueColor) |
 
891
                                   (1 << DirectColor)),
 
892
                                  8, PseudoColor, 0, 0, 0);
 
893
        break;
 
894
#if 0
 
895
    /* 12bit PseudoColor with 12bit color resolution
 
896
     * (to simulate SGI hardware and the 12bit PseudoColor emulation layer) */
 
897
    case 12:
 
898
        miSetVisualTypesAndMasks (12,
 
899
                                  ((1 << StaticGray) |
 
900
                                   (1 << GrayScale) |
 
901
                                   (1 << StaticColor) |
 
902
                                   (1 << PseudoColor) |
 
903
                                   (1 << TrueColor) |
 
904
                                   (1 << DirectColor)),
 
905
                                  12, PseudoColor, 0, 0, 0);
 
906
        break;
 
907
#endif
 
908
    case 15:
 
909
        miSetVisualTypesAndMasks (15,
 
910
                                  ((1 << TrueColor) |
 
911
                                   (1 << DirectColor)),
 
912
                                  8, TrueColor, 0x7c00, 0x03e0, 0x001f);
 
913
        break;
 
914
    case 16:
 
915
        miSetVisualTypesAndMasks (16,
 
916
                                  ((1 << TrueColor) |
 
917
                                   (1 << DirectColor)),
 
918
                                  8, TrueColor, 0xf800, 0x07e0, 0x001f);
 
919
        break;
 
920
    case 24:
 
921
        miSetVisualTypesAndMasks (24,
 
922
                                  ((1 << TrueColor) |
 
923
                                   (1 << DirectColor)),
 
924
                                  8, TrueColor, 0xff0000, 0x00ff00, 0x0000ff);
 
925
        break;
 
926
#if 0
 
927
    /* 30bit TrueColor (to simulate Sun's XVR-1000/-4000 high quality
 
928
     * framebuffer series) */
 
929
    case 30:
 
930
        miSetVisualTypesAndMasks (30,
 
931
                                  ((1 << TrueColor) |
 
932
                                   (1 << DirectColor)),
 
933
                                  10, TrueColor, 0x3ff00000, 0x000ffc00, 0x000003ff);
 
934
        break;
 
935
#endif
 
936
    }
 
937
        
 
938
    ret = fbScreenInit(pScreen, pbits, pvfb->width, pvfb->height,
 
939
                       dpix, dpiy, pvfb->paddedWidth,pvfb->bitsPerPixel);
 
940
#ifdef RENDER
 
941
    if (ret && Render) 
 
942
        fbPictureInit (pScreen, 0, 0);
 
943
#endif
 
944
 
 
945
    if (!ret) return FALSE;
 
946
 
 
947
    miInitializeBackingStore(pScreen);
 
948
 
 
949
    /*
 
950
     * Circumvent the backing store that was just initialised.  This amounts
 
951
     * to a truely bizarre way of initialising SaveDoomedAreas and friends.
 
952
     */
 
953
 
 
954
    pScreen->InstallColormap = vfbInstallColormap;
 
955
    pScreen->UninstallColormap = vfbUninstallColormap;
 
956
    pScreen->ListInstalledColormaps = vfbListInstalledColormaps;
 
957
 
 
958
    pScreen->SaveScreen = vfbSaveScreen;
 
959
    pScreen->StoreColors = vfbStoreColors;
 
960
 
 
961
    miDCInitialize(pScreen, &vfbPointerCursorFuncs);
 
962
 
 
963
    vfbWriteXWDFileHeader(pScreen);
 
964
 
 
965
    pScreen->blackPixel = pvfb->blackPixel;
 
966
    pScreen->whitePixel = pvfb->whitePixel;
 
967
 
 
968
    ret = fbCreateDefColormap(pScreen);
 
969
 
 
970
    miSetZeroLineBias(pScreen, pvfb->lineBias);
 
971
 
 
972
    pvfb->closeScreen = pScreen->CloseScreen;
 
973
    pScreen->CloseScreen = vfbCloseScreen;
 
974
 
 
975
    return ret;
 
976
 
 
977
} /* end vfbScreenInit */
 
978
 
 
979
 
 
980
void
 
981
InitOutput(ScreenInfo *screenInfo, int argc, char **argv)
 
982
{
 
983
    int i;
 
984
    int NumFormats = 0;
 
985
 
 
986
    /* initialize pixmap formats */
 
987
 
 
988
    /* must have a pixmap depth to match every screen depth */
 
989
    for (i = 0; i < vfbNumScreens; i++)
 
990
    {
 
991
        vfbPixmapDepths[vfbScreens[i].depth] = TRUE;
 
992
    }
 
993
 
 
994
    /* RENDER needs a good set of pixmaps. */
 
995
    if (Render) {
 
996
        vfbPixmapDepths[1] = TRUE;
 
997
        vfbPixmapDepths[4] = TRUE;
 
998
        vfbPixmapDepths[8] = TRUE;
 
999
#if 0
 
1000
        vfbPixmapDepths[12] = TRUE;
 
1001
#endif
 
1002
/*      vfbPixmapDepths[15] = TRUE; */
 
1003
        vfbPixmapDepths[16] = TRUE;
 
1004
        vfbPixmapDepths[24] = TRUE;
 
1005
#if 0
 
1006
        vfbPixmapDepths[30] = TRUE;
 
1007
#endif
 
1008
        vfbPixmapDepths[32] = TRUE;
 
1009
    }
 
1010
 
 
1011
    for (i = 1; i <= 32; i++)
 
1012
    {
 
1013
        if (vfbPixmapDepths[i])
 
1014
        {
 
1015
            if (NumFormats >= MAXFORMATS)
 
1016
                FatalError ("MAXFORMATS is too small for this server\n");
 
1017
            screenInfo->formats[NumFormats].depth = i;
 
1018
            screenInfo->formats[NumFormats].bitsPerPixel = vfbBitsPerPixel(i);
 
1019
            screenInfo->formats[NumFormats].scanlinePad = BITMAP_SCANLINE_PAD;
 
1020
            NumFormats++;
 
1021
        }
 
1022
    }
 
1023
 
 
1024
    screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
 
1025
    screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
 
1026
    screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
 
1027
    screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
 
1028
    screenInfo->numPixmapFormats = NumFormats;
 
1029
 
 
1030
    /* initialize screens */
 
1031
 
 
1032
    for (i = 0; i < vfbNumScreens; i++)
 
1033
    {
 
1034
        if (-1 == AddScreen(vfbScreenInit, argc, argv))
 
1035
        {
 
1036
            FatalError("Couldn't add screen %d", i);
 
1037
        }
 
1038
    }
 
1039
 
 
1040
} /* end InitOutput */
 
1041
 
 
1042
/* this is just to get the server to link on AIX */
 
1043
#ifdef AIXV3
 
1044
int SelectWaitTime = 10000; /* usec */
 
1045
#endif
 
1046