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

« back to all changes in this revision

Viewing changes to hw/kdrive/vesa/vesa.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
/* 
 
2
Copyright (c) 2000 by Juliusz Chroboczek
 
3
 
 
4
Permission is hereby granted, free of charge, to any person obtaining a copy
 
5
of this software and associated documentation files (the "Software"), to deal
 
6
in the Software without restriction, including without limitation the rights
 
7
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
8
copies of the Software, and to permit persons to whom the Software is
 
9
furnished to do so, subject to the following conditions: 
 
10
 
 
11
The above copyright notice and this permission notice shall be included in
 
12
all copies or substantial portions of the Software. 
 
13
 
 
14
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
15
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
16
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
17
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
18
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
19
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
20
THE SOFTWARE.
 
21
*/
 
22
/* $Id: vesa.c,v 1.36 2005/12/27 08:29:50 ajax Exp $ */
 
23
 
 
24
#ifdef HAVE_CONFIG_H
 
25
#include <kdrive-config.h>
 
26
#endif
 
27
#include "vesa.h"
 
28
#include "vga.h"
 
29
#include "vbe.h"
 
30
#ifdef RANDR
 
31
#include <randrstr.h>
 
32
#endif
 
33
 
 
34
int vesa_video_mode = 0;
 
35
Bool vesa_force_mode = FALSE;
 
36
Bool vesa_swap_rgb = FALSE;
 
37
Bool vesa_shadow = FALSE;
 
38
Bool vesa_linear_fb = TRUE;
 
39
Bool vesa_restore = FALSE;
 
40
Bool vesa_verbose = FALSE;
 
41
Bool vesa_force_text = FALSE;
 
42
Bool vesa_restore_font = TRUE;
 
43
Bool vesa_map_holes = TRUE;
 
44
Bool vesa_boot = FALSE;
 
45
 
 
46
#define VesaPriv(scr)   ((VesaScreenPrivPtr) (scr)->driver)
 
47
 
 
48
#define vesaWidth(scr,vmib) ((vmib)->XResolution)
 
49
#define vesaHeight(scr,vmib) ((vmib)->YResolution)
 
50
 
 
51
static Bool
 
52
vesaComputeFramebufferMapping (KdScreenInfo *screen);
 
53
 
 
54
static Bool
 
55
vesaMapFramebuffer (KdScreenInfo    *screen);
 
56
    
 
57
static Bool
 
58
vesaModeSupportable (VesaModePtr mode, Bool complain)
 
59
{
 
60
    if((mode->ModeAttributes & 0x10) == 0) {
 
61
        if(complain)
 
62
            ErrorF("Text mode specified.\n");
 
63
        return FALSE;
 
64
    }
 
65
    if(mode->MemoryModel != 0x06 && mode->MemoryModel != 0x04 && mode->MemoryModel != 0x03) {
 
66
        if(complain)
 
67
            ErrorF("Unsupported memory model 0x%X\n", mode->MemoryModel);
 
68
        return FALSE;
 
69
    }
 
70
    if((mode->ModeAttributes & 0x80) == 0) {
 
71
        if ((mode->ModeAttributes & 0x40) != 0) {
 
72
            if(complain)
 
73
                ErrorF("Neither linear nor windowed framebuffer available in this mode\n");
 
74
            return FALSE;
 
75
        }
 
76
    }
 
77
    if(!(mode->ModeAttributes & 1)) {
 
78
        if(complain)
 
79
            ErrorF("Mode not supported on this hardware\n");
 
80
        return FALSE;
 
81
    }
 
82
    return TRUE;
 
83
}
 
84
 
 
85
static Bool
 
86
vesaModeSupported (VesaCardPrivPtr priv, VesaModePtr mode, Bool complain)
 
87
{
 
88
    if (!priv->vbeInfo && mode->vbe) {
 
89
        if (complain)
 
90
            ErrorF("VBE bios mode not usable.\n");
 
91
        return FALSE;
 
92
    }
 
93
    return vesaModeSupportable (mode, complain);
 
94
}
 
95
 
 
96
void
 
97
vesaReportMode (VesaModePtr mode)
 
98
{
 
99
    int supported = (mode->ModeAttributes&MODE_SUPPORTED)?1:0;
 
100
    int colour = (mode->ModeAttributes&MODE_COLOUR)?1:0;
 
101
    int graphics = (mode->ModeAttributes&MODE_GRAPHICS)?1:0;
 
102
    int vga_compatible = !((mode->ModeAttributes&MODE_VGA)?1:0);
 
103
    int linear_fb = (mode->ModeAttributes&MODE_LINEAR)?1:0;
 
104
 
 
105
    ErrorF("0x%04X: %dx%dx%d%s%s",
 
106
           (unsigned)mode->mode, 
 
107
           (int)mode->XResolution, (int)mode->YResolution,
 
108
           vesaDepth (mode),
 
109
           colour?"":" (monochrome)",
 
110
           graphics?"":" (graphics)",
 
111
           vga_compatible?"":" (vga compatible)",
 
112
           linear_fb?"":" (linear frame buffer)");
 
113
    switch(mode->MemoryModel) {
 
114
    case MEMORY_TEXT:
 
115
        ErrorF(" text mode");
 
116
        break;
 
117
    case MEMORY_CGA:
 
118
        ErrorF(" CGA graphics");
 
119
        break;
 
120
    case MEMORY_HERCULES:
 
121
        ErrorF(" Hercules graphics");
 
122
        break;
 
123
    case MEMORY_PLANAR:
 
124
        ErrorF(" Planar (%d planes)", mode->NumberOfPlanes);
 
125
        break;
 
126
    case MEMORY_PSEUDO:
 
127
        ErrorF(" PseudoColor");
 
128
        break;
 
129
    case MEMORY_NONCHAIN:
 
130
        ErrorF(" Non-chain 4, 256 colour");
 
131
        break;
 
132
    case MEMORY_DIRECT:
 
133
        if(mode->DirectColorModeInfo & MODE_DIRECT)
 
134
            ErrorF(" DirectColor");
 
135
        else
 
136
            ErrorF(" TrueColor");
 
137
        ErrorF(" [%d:%d:%d:%d]",
 
138
               mode->RedMaskSize, mode->GreenMaskSize, mode->BlueMaskSize,
 
139
               mode->RsvdMaskSize);
 
140
        if(mode->DirectColorModeInfo & 2)
 
141
            ErrorF(" (reserved bits are reserved)");
 
142
        break;
 
143
    case MEMORY_YUV:
 
144
        ErrorF("YUV");
 
145
        break;
 
146
    default:
 
147
        ErrorF("unknown MemoryModel 0x%X ", mode->MemoryModel);
 
148
    }
 
149
    if(!supported)
 
150
        ErrorF(" (unsupported)");
 
151
    else if(!linear_fb)
 
152
        ErrorF(" (no linear framebuffer)");
 
153
    ErrorF("\n");
 
154
}
 
155
 
 
156
VesaModePtr
 
157
vesaGetModes (Vm86InfoPtr vi, int *ret_nmode)
 
158
{
 
159
    VesaModePtr         modes;
 
160
    int                 nmode, nmodeVbe, nmodeVga;
 
161
    int                 code;
 
162
    
 
163
    code = VgaGetNmode (vi);
 
164
    if (code <= 0)
 
165
        nmodeVga = 0;
 
166
    else
 
167
        nmodeVga = code;
 
168
    
 
169
    code = VbeGetNmode (vi);
 
170
    if (code <= 0)
 
171
        nmodeVbe = 0;
 
172
    else
 
173
        nmodeVbe = code;
 
174
 
 
175
    nmode = nmodeVga + nmodeVbe;
 
176
    if (nmode <= 0)
 
177
        return 0;
 
178
    
 
179
    modes = xalloc (nmode * sizeof (VesaModeRec));
 
180
    
 
181
    memset (modes, '\0', nmode * sizeof (VesaModeRec));
 
182
    
 
183
    if (nmodeVga)
 
184
    {
 
185
        code = VgaGetModes (vi, modes, nmodeVga);
 
186
        if (code <= 0)
 
187
            nmodeVga = 0;
 
188
        else
 
189
            nmodeVga = code;
 
190
    }
 
191
 
 
192
    if (nmodeVbe)
 
193
    {
 
194
        code = VbeGetModes (vi, modes + nmodeVga, nmodeVbe);
 
195
        if (code <= 0)
 
196
            nmodeVbe = 0;
 
197
        else
 
198
            nmodeVbe = code;
 
199
    }
 
200
    
 
201
    nmode = nmodeVga + nmodeVbe;
 
202
 
 
203
    if (nmode == 0)
 
204
    {
 
205
        xfree (modes);
 
206
        modes = 0;
 
207
        return 0;
 
208
    }
 
209
    *ret_nmode = nmode;
 
210
    return modes;
 
211
}
 
212
 
 
213
Bool
 
214
vesaInitialize (KdCardInfo *card, VesaCardPrivPtr priv)
 
215
{
 
216
    priv->vi = Vm86Setup(vesa_map_holes);
 
217
    if(!priv->vi)
 
218
        goto fail;
 
219
 
 
220
    if (vesa_boot)
 
221
        VbeBoot (priv->vi);
 
222
 
 
223
    priv->modes = vesaGetModes (priv->vi, &priv->nmode);
 
224
        
 
225
    if (!priv->modes)
 
226
        goto fail;
 
227
 
 
228
    priv->vbeInfo = VbeInit (priv->vi);
 
229
    
 
230
    card->driver = priv;
 
231
 
 
232
    return TRUE;
 
233
 
 
234
fail:
 
235
    if(priv->vi)
 
236
        Vm86Cleanup(priv->vi);
 
237
    return FALSE;
 
238
}
 
239
 
 
240
void
 
241
vesaListModes (void)
 
242
{
 
243
    Vm86InfoPtr vi;
 
244
    VesaModePtr modes;
 
245
    int         nmode;
 
246
    int         n;
 
247
 
 
248
    vi = Vm86Setup (vesa_map_holes);
 
249
    if (!vi)
 
250
    {
 
251
        ErrorF ("Can't setup vm86\n");
 
252
    }
 
253
    else
 
254
    {
 
255
        modes = vesaGetModes (vi, &nmode);
 
256
        if (!modes)
 
257
        {
 
258
            ErrorF ("No modes available\n");
 
259
        }
 
260
        else
 
261
        {
 
262
            VbeReportInfo (vi);
 
263
            for (n = 0; n < nmode; n++)
 
264
            {
 
265
                if (vesa_force_mode || vesaModeSupportable (modes+n, 0))
 
266
                    vesaReportMode (modes+n);
 
267
            }
 
268
            xfree (modes);
 
269
        }
 
270
        Vm86Cleanup (vi);
 
271
    }
 
272
}
 
273
 
 
274
void
 
275
vesaTestMode (void)
 
276
{
 
277
    Vm86InfoPtr vi;
 
278
    VesaModePtr modes;
 
279
    VesaModePtr mode;
 
280
    VbeInfoPtr  vbeInfo;
 
281
    int         nmode;
 
282
    int         n;
 
283
 
 
284
    vi = Vm86Setup (vesa_map_holes);
 
285
    if (!vi)
 
286
    {
 
287
        ErrorF ("Can't setup vm86\n");
 
288
        return;
 
289
    }
 
290
    modes = vesaGetModes (vi, &nmode);
 
291
    if (!modes)
 
292
    {
 
293
        ErrorF ("No modes available\n");
 
294
        return;
 
295
    }
 
296
    VbeReportInfo (vi);
 
297
    vbeInfo = VbeInit (vi);
 
298
    for (n = 0; n < nmode; n++)
 
299
    {
 
300
        if (modes[n].mode == vesa_video_mode)
 
301
            break;
 
302
    }
 
303
    if (n == nmode)
 
304
    {
 
305
        ErrorF ("no mode specified\n");
 
306
        return;
 
307
    }
 
308
    mode = &modes[n];
 
309
    if (mode->vbe)
 
310
    {
 
311
        ErrorF ("Enable VBE mode 0x%x\n", mode->mode);
 
312
        VbeSetMode(vi, vbeInfo, mode->mode, FALSE, FALSE);
 
313
    }
 
314
    else
 
315
    {
 
316
        ErrorF ("Enable BIOS mode 0x%x\n", mode->mode);
 
317
        VgaSetMode (vi, mode->mode);
 
318
    }
 
319
    sleep (2);
 
320
    ErrorF ("Restore BIOS mode 0x%x\n", 3);
 
321
    VgaSetMode (vi, 3);
 
322
    xfree (modes);
 
323
    Vm86Cleanup (vi);
 
324
}
 
325
 
 
326
Bool
 
327
vesaCardInit(KdCardInfo *card)
 
328
{
 
329
    VesaCardPrivPtr priv;
 
330
 
 
331
    priv = xalloc(sizeof(VesaCardPrivRec));
 
332
    if(!priv)
 
333
        return FALSE;
 
334
 
 
335
    if (!vesaInitialize (card, priv))
 
336
    {
 
337
        xfree(priv);
 
338
        return FALSE;
 
339
    }
 
340
    
 
341
    return TRUE;
 
342
}
 
343
 
 
344
int
 
345
vesaDepth (VesaModePtr mode)
 
346
{
 
347
    if (mode->MemoryModel == MEMORY_DIRECT)
 
348
        return (mode->RedMaskSize +
 
349
                mode->GreenMaskSize +
 
350
                mode->BlueMaskSize);
 
351
    else
 
352
        return mode->BitsPerPixel;
 
353
}
 
354
 
 
355
Bool
 
356
vesaModeGood (KdScreenInfo  *screen,
 
357
              VesaModePtr   a)
 
358
{
 
359
    if (vesaWidth(screen,a) <= screen->width &&
 
360
        vesaHeight(screen,a) <= screen->height &&
 
361
        vesaDepth (a) >= screen->fb[0].depth)
 
362
    {
 
363
        return TRUE;
 
364
    }
 
365
    return FALSE;
 
366
}
 
367
 
 
368
#define vabs(a) ((a) >= 0 ? (a) : -(a))
 
369
 
 
370
int
 
371
vesaSizeError (KdScreenInfo *screen,
 
372
               VesaModePtr  a)
 
373
{
 
374
    int     xdist, ydist;
 
375
    xdist = vabs (screen->width - vesaWidth(screen,a));
 
376
    ydist = vabs (screen->height - vesaHeight(screen,a));
 
377
    return xdist * xdist + ydist * ydist;
 
378
}
 
379
 
 
380
Bool
 
381
vesaModeBetter (KdScreenInfo    *screen,
 
382
                VesaModePtr     a,
 
383
                VesaModePtr     b)
 
384
{
 
385
    int     aerr, berr;
 
386
 
 
387
    if (vesaModeGood (screen, a))
 
388
    {
 
389
        if (!vesaModeGood (screen, b))
 
390
            return TRUE;
 
391
    }
 
392
    else
 
393
    {
 
394
        if (vesaModeGood (screen, b))
 
395
            return FALSE;
 
396
    }
 
397
    aerr = vesaSizeError (screen, a);
 
398
    berr = vesaSizeError (screen, b);
 
399
    if (aerr < berr)
 
400
        return TRUE;
 
401
    if (berr < aerr)
 
402
        return FALSE;
 
403
    if (vabs (screen->fb[0].depth - vesaDepth (a)) < 
 
404
        vabs (screen->fb[0].depth - vesaDepth (b)))
 
405
        return TRUE;
 
406
    if (a->BitsPerPixel == 32 && b->BitsPerPixel == 24)
 
407
        return TRUE;
 
408
    return FALSE;
 
409
}
 
410
 
 
411
VesaModePtr
 
412
vesaSelectMode (KdScreenInfo *screen)
 
413
{
 
414
    VesaCardPrivPtr priv = screen->card->driver;
 
415
    int             i, best;
 
416
    
 
417
    if (vesa_video_mode)
 
418
    {
 
419
        for (best = 0; best < priv->nmode; best++)
 
420
            if (priv->modes[best].mode == vesa_video_mode &&
 
421
                (vesaModeSupported (priv, &priv->modes[best], FALSE) ||
 
422
                 vesa_force_mode))
 
423
                return &priv->modes[best];
 
424
    }
 
425
    for (best = 0; best < priv->nmode; best++)
 
426
    {
 
427
        if (vesaModeSupported (priv, &priv->modes[best], FALSE))
 
428
            break;
 
429
    }
 
430
    if (best == priv->nmode)
 
431
        return 0;
 
432
    for (i = best + 1; i < priv->nmode; i++)
 
433
        if (vesaModeSupported (priv, &priv->modes[i], FALSE) &&
 
434
            vesaModeBetter (screen, &priv->modes[i], 
 
435
                            &priv->modes[best]))
 
436
            best = i;
 
437
    return &priv->modes[best];
 
438
}   
 
439
    
 
440
Bool
 
441
vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr)
 
442
{
 
443
    VesaModePtr         mode;
 
444
 
 
445
    screen->driver = pscr;
 
446
    
 
447
    if (!screen->width || !screen->height)
 
448
    {
 
449
        screen->width = 640;
 
450
        screen->height = 480;
 
451
    }
 
452
    if (!screen->fb[0].depth)
 
453
        screen->fb[0].depth = 4;
 
454
    
 
455
    if (vesa_verbose)
 
456
        ErrorF ("Mode requested %dx%dx%d\n",
 
457
                screen->width, screen->height, screen->fb[0].depth);
 
458
    
 
459
    mode = vesaSelectMode (screen);
 
460
    
 
461
    if (!mode)
 
462
    {
 
463
        if (vesa_verbose)
 
464
            ErrorF ("No selectable mode\n");
 
465
        return FALSE;
 
466
    }
 
467
    pscr->mode = *mode;
 
468
 
 
469
    if (vesa_verbose)
 
470
    {
 
471
        ErrorF ("\t");
 
472
        vesaReportMode (&pscr->mode);
 
473
    }
 
474
    
 
475
    pscr->randr = screen->randr;
 
476
    pscr->shadow = vesa_shadow;
 
477
    pscr->origDepth = screen->fb[0].depth;
 
478
    /*
 
479
     * Compute visual support for the selected depth
 
480
     */
 
481
    
 
482
    switch (pscr->mode.MemoryModel) {
 
483
    case MEMORY_DIRECT:
 
484
        /* TrueColor or DirectColor */
 
485
        screen->fb[0].visuals = (1 << TrueColor);
 
486
        screen->fb[0].redMask = 
 
487
            FbStipMask(pscr->mode.RedFieldPosition, pscr->mode.RedMaskSize);
 
488
        screen->fb[0].greenMask = 
 
489
            FbStipMask(pscr->mode.GreenFieldPosition, pscr->mode.GreenMaskSize);
 
490
        screen->fb[0].blueMask = 
 
491
            FbStipMask(pscr->mode.BlueFieldPosition, pscr->mode.BlueMaskSize);
 
492
        break;
 
493
    case MEMORY_PSEUDO:
 
494
        /* PseudoColor */
 
495
        screen->fb[0].visuals = ((1 << StaticGray) |
 
496
                                 (1 << GrayScale) |
 
497
                                 (1 << StaticColor) |
 
498
                                 (1 << PseudoColor) |
 
499
                                 (1 << TrueColor) |
 
500
                                 (1 << DirectColor));
 
501
        screen->fb[0].blueMask  = 0x00;
 
502
        screen->fb[0].greenMask = 0x00;
 
503
        screen->fb[0].redMask   = 0x00;
 
504
        break;
 
505
    case MEMORY_PLANAR:
 
506
        /* 4 plane planar */
 
507
        if (pscr->mode.ModeAttributes & MODE_COLOUR)
 
508
            screen->fb[0].visuals = (1 << StaticColor);
 
509
        else
 
510
            screen->fb[0].visuals = (1 << StaticGray);
 
511
        screen->fb[0].blueMask  = 0x00;
 
512
        screen->fb[0].greenMask = 0x00;
 
513
        screen->fb[0].redMask   = 0x00;
 
514
        break;
 
515
    default:
 
516
        ErrorF("Unsupported VESA MemoryModel 0x%02X\n",
 
517
               pscr->mode.MemoryModel);
 
518
        return FALSE;
 
519
    }
 
520
    screen->rate = 72;
 
521
 
 
522
    if (!vesaComputeFramebufferMapping (screen))
 
523
        return FALSE;
 
524
    if (!vesaMapFramebuffer (screen))
 
525
        return FALSE;
 
526
    return TRUE;
 
527
}
 
528
 
 
529
Bool
 
530
vesaScreenInit(KdScreenInfo *screen)
 
531
{
 
532
    VesaScreenPrivPtr   pscr;
 
533
    
 
534
    pscr = xcalloc (1, sizeof (VesaScreenPrivRec));
 
535
    if (!pscr)
 
536
        return FALSE;
 
537
    if (!vesaScreenInitialize (screen, pscr))
 
538
        return FALSE;
 
539
    return TRUE;
 
540
}
 
541
 
 
542
void *
 
543
vesaSetWindowPlanar(ScreenPtr pScreen,
 
544
                  CARD32    row,
 
545
                  CARD32    offset,
 
546
                  int       mode,
 
547
                  CARD32    *size)
 
548
{
 
549
    KdScreenPriv(pScreen);
 
550
    VesaCardPrivPtr     priv = pScreenPriv->card->driver;
 
551
    VesaScreenPrivPtr   pscr = pScreenPriv->screen->driver;
 
552
    static int          plane;
 
553
    int                 winSize;
 
554
    void                *base;
 
555
 
 
556
    plane = offset & 3;
 
557
    VgaSetWritePlaneMask (priv->vi, (1 << plane));
 
558
    offset = offset >> 2;
 
559
    if (pscr->mode.vbe)
 
560
    {
 
561
        base = VbeSetWindow (priv->vi,
 
562
                             priv->vbeInfo,
 
563
                             pscr->mode.BytesPerScanLine * row + offset,
 
564
                             mode,
 
565
                             &winSize);
 
566
    }
 
567
    else
 
568
    {
 
569
        base = VgaSetWindow (priv->vi,
 
570
                             pscr->mode.mode,
 
571
                             pscr->mode.BytesPerScanLine * row + offset,
 
572
                             mode,
 
573
                             &winSize);
 
574
    }
 
575
    *size = (CARD32) winSize;
 
576
    return base;
 
577
}
 
578
 
 
579
void *
 
580
vesaSetWindowLinear (ScreenPtr  pScreen,
 
581
                     CARD32     row,
 
582
                     CARD32     offset,
 
583
                     int        mode,
 
584
                     CARD32     *size)
 
585
{
 
586
    KdScreenPriv(pScreen);
 
587
    VesaScreenPrivPtr   pscr = pScreenPriv->screen->driver;
 
588
 
 
589
    *size = pscr->mode.BytesPerScanLine;
 
590
    return (CARD8 *) pscr->fb + row * pscr->mode.BytesPerScanLine + offset;
 
591
}
 
592
 
 
593
void *
 
594
vesaSetWindowWindowed (ScreenPtr    pScreen,
 
595
                       CARD32       row,
 
596
                       CARD32       offset,
 
597
                       int          mode,
 
598
                       CARD32       *size)
 
599
{
 
600
    KdScreenPriv(pScreen);
 
601
    VesaCardPrivPtr     priv = pScreenPriv->card->driver;
 
602
    VesaScreenPrivPtr   pscr = pScreenPriv->screen->driver;
 
603
    int                 winSize;
 
604
    void                *base;
 
605
 
 
606
    if (pscr->mode.vbe)
 
607
    {
 
608
        base = VbeSetWindow (priv->vi,
 
609
                             priv->vbeInfo,
 
610
                             pscr->mode.BytesPerScanLine * row + offset,
 
611
                             mode,
 
612
                             &winSize);
 
613
    }
 
614
    else
 
615
    {
 
616
        base = VgaSetWindow (priv->vi,
 
617
                             pscr->mode.mode,
 
618
                             pscr->mode.BytesPerScanLine * row + offset,
 
619
                             mode,
 
620
                             &winSize);
 
621
    }
 
622
    *size = (CARD32) winSize;
 
623
    return base;
 
624
}
 
625
 
 
626
void *
 
627
vesaWindowPlanar (ScreenPtr pScreen,
 
628
                  CARD32    row,
 
629
                  CARD32    offset,
 
630
                  int       mode,
 
631
                  CARD32    *size,
 
632
                  void      *closure)
 
633
{
 
634
    KdScreenPriv(pScreen);
 
635
 
 
636
    if (!pScreenPriv->enabled)
 
637
        return 0;
 
638
    return vesaSetWindowPlanar (pScreen, row, offset, mode, size);
 
639
}
 
640
 
 
641
void *
 
642
vesaWindowLinear (ScreenPtr pScreen,
 
643
                  CARD32    row,
 
644
                  CARD32    offset,
 
645
                  int       mode,
 
646
                  CARD32    *size,
 
647
                  void      *closure)
 
648
{
 
649
    KdScreenPriv(pScreen);
 
650
 
 
651
    if (!pScreenPriv->enabled)
 
652
        return 0;
 
653
    return vesaSetWindowLinear (pScreen, row, offset, mode, size);
 
654
}
 
655
 
 
656
void *
 
657
vesaWindowWindowed (ScreenPtr   pScreen,
 
658
                    CARD32      row,
 
659
                    CARD32      offset,
 
660
                    int         mode,
 
661
                    CARD32      *size,
 
662
                    void        *closure)
 
663
{
 
664
    KdScreenPriv(pScreen);
 
665
 
 
666
    if (!pScreenPriv->enabled)
 
667
        return 0;
 
668
    return vesaSetWindowWindowed (pScreen, row, offset, mode, size);
 
669
}
 
670
 
 
671
#define vesaInvertBits32(v) { \
 
672
    v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); \
 
673
    v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); \
 
674
    v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); \
 
675
}
 
676
 
 
677
void *
 
678
vesaWindowCga (ScreenPtr    pScreen,
 
679
               CARD32       row,
 
680
               CARD32       offset,
 
681
               int          mode,
 
682
               CARD32       *size,
 
683
               void         *closure)
 
684
{
 
685
    KdScreenPriv(pScreen);
 
686
    VesaScreenPrivPtr   pscr = pScreenPriv->screen->driver;
 
687
    int                 line;
 
688
    
 
689
    if (!pScreenPriv->enabled)
 
690
        return 0;
 
691
    *size = pscr->mode.BytesPerScanLine;
 
692
    line = ((row & 1) << 13) + (row >> 1) * pscr->mode.BytesPerScanLine;
 
693
    return (CARD8 *) pscr->fb + line + offset;
 
694
}
 
695
 
 
696
void
 
697
vesaUpdateMono (ScreenPtr       pScreen,
 
698
                shadowBufPtr    pBuf)
 
699
{
 
700
    RegionPtr   damage = shadowDamage(pBuf);
 
701
    PixmapPtr   pShadow = pBuf->pPixmap;
 
702
    int         nbox = REGION_NUM_RECTS (damage);
 
703
    BoxPtr      pbox = REGION_RECTS (damage);
 
704
    FbBits      *shaBase, *shaLine, *sha;
 
705
    FbStride    shaStride;
 
706
    int         scrBase, scrLine, scr;
 
707
    int         shaBpp;
 
708
    int         shaXoff, shaYoff;   /* XXX assumed to be zero */
 
709
    int         x, y, w, h, width;
 
710
    int         i;
 
711
    FbBits      *winBase = 0, *win;
 
712
    CARD32      winSize;
 
713
    FbBits      bits;
 
714
 
 
715
    fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff);
 
716
    while (nbox--)
 
717
    {
 
718
        x = pbox->x1 * shaBpp;
 
719
        y = pbox->y1;
 
720
        w = (pbox->x2 - pbox->x1) * shaBpp;
 
721
        h = pbox->y2 - pbox->y1;
 
722
 
 
723
        scrLine = (x >> FB_SHIFT);
 
724
        shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
 
725
                                   
 
726
        x &= FB_MASK;
 
727
        w = (w + x + FB_MASK) >> FB_SHIFT;
 
728
        
 
729
        while (h--)
 
730
        {
 
731
            winSize = 0;
 
732
            scrBase = 0;
 
733
            width = w;
 
734
            scr = scrLine;
 
735
            sha = shaLine;
 
736
            while (width) {
 
737
                /* how much remains in this window */
 
738
                i = scrBase + winSize - scr;
 
739
                if (i <= 0 || scr < scrBase)
 
740
                {
 
741
                    winBase = (FbBits *) (*pBuf->window) (pScreen,
 
742
                                                          y,
 
743
                                                          scr * sizeof (FbBits),
 
744
                                                          SHADOW_WINDOW_WRITE,
 
745
                                                          &winSize,
 
746
                                                          pBuf->closure);
 
747
                    if(!winBase)
 
748
                        return;
 
749
                    scrBase = scr;
 
750
                    winSize /= sizeof (FbBits);
 
751
                    i = winSize;
 
752
                }
 
753
                win = winBase + (scr - scrBase);
 
754
                if (i > width)
 
755
                    i = width;
 
756
                width -= i;
 
757
                scr += i;
 
758
                while (i--)
 
759
                {
 
760
                    bits = *sha++;
 
761
                    vesaInvertBits32(bits);
 
762
                    *win++ = bits;
 
763
                }
 
764
            }
 
765
            shaLine += shaStride;
 
766
            y++;
 
767
        }
 
768
        pbox++;
 
769
    }
 
770
}
 
771
 
 
772
static const CARD16     vga16Colors[16][3] = {
 
773
    { 0,   0,   0,   },       /*  0 */
 
774
    { 0,   0,   0xAA,},       /*  1 */
 
775
    { 0,   0xAA,0,   },       /*  2 */
 
776
    { 0,   0xAA,0xAA,},       /*  3 */
 
777
    { 0xAA,0,   0,   },       /*  4 */
 
778
    { 0xAA,0,   0xAA,},       /*  5 */
 
779
    { 0xAA,0x55,0,   },       /*  6 */
 
780
    { 0xAA,0xAA,0xAA,},       /*  7 */
 
781
    { 0x55,0x55,0x55,},       /*  8 */
 
782
    { 0x55,0x55,0xFF,},       /*  9 */
 
783
    { 0x55,0xFF,0x55,},       /* 10 */
 
784
    { 0x55,0xFF,0xFF,},       /* 11 */
 
785
    { 0xFF,0x55,0x55,},       /* 12 */
 
786
    { 0xFF,0x55,0xFF,},       /* 13 */
 
787
    { 0xFF,0xFF,0x55,},       /* 14 */
 
788
    { 0xFF,0xFF,0xFF,},       /* 15 */
 
789
};
 
790
 
 
791
Bool
 
792
vesaCreateColormap16 (ColormapPtr pmap)
 
793
{
 
794
    int     i, j;
 
795
 
 
796
    if (pmap->pVisual->ColormapEntries == 16)
 
797
    for (i = 0; i < pmap->pVisual->ColormapEntries; i++)
 
798
    {
 
799
        j = i & 0xf;
 
800
        pmap->red[i].co.local.red = (vga16Colors[j][0]<<8)|vga16Colors[j][0];
 
801
        pmap->red[i].co.local.green = (vga16Colors[j][1]<<8)|vga16Colors[j][1];
 
802
        pmap->red[i].co.local.blue = (vga16Colors[j][2]<<8)|vga16Colors[j][2];
 
803
    }
 
804
    return TRUE;
 
805
}
 
806
 
 
807
void
 
808
vesaSetScreenSizes (ScreenPtr pScreen)
 
809
{
 
810
    KdScreenPriv(pScreen);
 
811
    KdScreenInfo        *screen = pScreenPriv->screen;
 
812
    VesaScreenPrivPtr   pscr = screen->driver;
 
813
 
 
814
    if (pscr->randr & (RR_Rotate_0|RR_Rotate_180))
 
815
    {
 
816
        pScreen->width = pscr->mode.XResolution;
 
817
        pScreen->height = pscr->mode.YResolution;
 
818
        pScreen->mmWidth = screen->width_mm;
 
819
        pScreen->mmHeight = screen->height_mm;
 
820
    }
 
821
    else
 
822
    {
 
823
        pScreen->width = pscr->mode.YResolution;
 
824
        pScreen->height = pscr->mode.XResolution;
 
825
        pScreen->mmWidth = screen->height_mm;
 
826
        pScreen->mmHeight = screen->width_mm;
 
827
    }
 
828
}
 
829
 
 
830
Bool
 
831
vesaSetShadow (ScreenPtr pScreen)
 
832
{
 
833
    KdScreenPriv(pScreen);
 
834
    VesaScreenPrivPtr   pscr = pScreenPriv->screen->driver;
 
835
    ShadowUpdateProc    update;
 
836
    ShadowWindowProc    window = 0;
 
837
 
 
838
    if (pscr->randr != RR_Rotate_0)
 
839
        update = shadowUpdateRotatePacked;
 
840
    else
 
841
        update = shadowUpdatePacked;
 
842
    switch (pscr->mapping) {
 
843
    case VESA_LINEAR:
 
844
        window = vesaWindowLinear;
 
845
        break;
 
846
    case VESA_WINDOWED:
 
847
        window = vesaWindowWindowed;
 
848
        break;
 
849
    case VESA_PLANAR:
 
850
        if (pScreenPriv->screen->fb[0].bitsPerPixel == 8)
 
851
            update = shadowUpdatePlanar4x8;
 
852
        else
 
853
            update = shadowUpdatePlanar4;
 
854
        window = vesaWindowPlanar;
 
855
        break;
 
856
    case VESA_MONO:
 
857
        update = vesaUpdateMono;
 
858
        if (pscr->mode.mode < 8)
 
859
            window = vesaWindowCga;
 
860
        else
 
861
            window = vesaWindowLinear;
 
862
        break;
 
863
    }
 
864
    
 
865
    return KdShadowSet (pScreen, pscr->randr, update, window);
 
866
}
 
867
 
 
868
static Bool
 
869
vesaComputeFramebufferMapping (KdScreenInfo *screen)
 
870
{
 
871
    VesaScreenPrivPtr   pscr = screen->driver;
 
872
    int                 depth, bpp, fbbpp;
 
873
    Pixel               allbits;
 
874
    KdMouseMatrix       m;
 
875
 
 
876
    if (vesa_linear_fb)
 
877
    {
 
878
        pscr->mapping = VESA_LINEAR;
 
879
        pscr->shadow = FALSE;
 
880
    }
 
881
    else
 
882
    {
 
883
        pscr->mapping = VESA_WINDOWED;
 
884
        pscr->shadow = TRUE;
 
885
    }
 
886
    
 
887
    depth = vesaDepth (&pscr->mode);
 
888
    bpp = pscr->mode.BitsPerPixel;
 
889
    
 
890
    if (bpp > 24)
 
891
        bpp = 32;
 
892
    else if (bpp > 16)
 
893
        bpp = 24;
 
894
    else if (bpp > 8)
 
895
        bpp = 16;
 
896
    else if (bpp > 4)
 
897
        bpp = 8;
 
898
    else if (bpp > 1)
 
899
        bpp = 4;
 
900
    else
 
901
        bpp = 1;
 
902
    fbbpp = bpp;
 
903
    
 
904
    switch (pscr->mode.MemoryModel) {
 
905
    case MEMORY_DIRECT:
 
906
        allbits = (screen->fb[0].redMask | 
 
907
                   screen->fb[0].greenMask | 
 
908
                   screen->fb[0].blueMask);
 
909
        depth = 32;
 
910
        while (depth && !(allbits & (1 << (depth - 1))))
 
911
            depth--;
 
912
        if (vesa_verbose)
 
913
            ErrorF ("\tTrue Color %d/%d red 0x%x green 0x%x blue 0x%x\n",
 
914
                    bpp, depth, 
 
915
                    screen->fb[0].redMask,
 
916
                    screen->fb[0].greenMask,
 
917
                    screen->fb[0].blueMask);
 
918
        break;
 
919
    case MEMORY_PSEUDO:
 
920
        if (vesa_verbose)
 
921
            ErrorF ("\tPseudo Color bpp %d depth %d\n",
 
922
                    bpp, depth);
 
923
        break;
 
924
    case MEMORY_PLANAR:
 
925
        if (bpp == 4)
 
926
        {
 
927
            bpp = screen->fb[0].bitsPerPixel;
 
928
            if (bpp != 8)
 
929
                bpp = 4;
 
930
            depth = bpp;
 
931
        }
 
932
        if (bpp == 1)
 
933
        {
 
934
            pscr->mapping = VESA_MONO;
 
935
            if (vesa_verbose)
 
936
                ErrorF ("\tMonochrome\n");
 
937
        }
 
938
        else
 
939
        {
 
940
            pscr->mapping = VESA_PLANAR;
 
941
            if (vesa_verbose)
 
942
                ErrorF ("\tStatic color bpp %d depth %d\n",
 
943
                        bpp, depth);
 
944
        }
 
945
        pscr->randr = RR_Rotate_0;
 
946
        pscr->shadow = TRUE;
 
947
        break;
 
948
    default:
 
949
        return FALSE;
 
950
    }
 
951
 
 
952
    switch (fbbpp) {
 
953
    case 8:
 
954
    case 16:
 
955
    case 32:
 
956
        break;
 
957
    default:
 
958
        pscr->randr = RR_Rotate_0;
 
959
        break;
 
960
    }
 
961
    
 
962
    if (pscr->randr != RR_Rotate_0)
 
963
        pscr->shadow = TRUE;
 
964
    
 
965
    if (vesa_shadow)
 
966
        pscr->shadow = vesa_shadow;
 
967
 
 
968
    if (pscr->mapping == VESA_LINEAR && !(pscr->mode.ModeAttributes & MODE_LINEAR))
 
969
    {
 
970
        pscr->mapping = VESA_WINDOWED;
 
971
        pscr->shadow = TRUE;
 
972
    }
 
973
    KdComputeMouseMatrix (&m, pscr->randr, 
 
974
                          pscr->mode.XResolution, pscr->mode.YResolution);
 
975
    
 
976
    KdSetMouseMatrix (&m);
 
977
    
 
978
    screen->width = pscr->mode.XResolution;
 
979
    screen->height = pscr->mode.YResolution;
 
980
    screen->fb[0].depth = depth;
 
981
    screen->fb[0].bitsPerPixel = bpp;
 
982
 
 
983
    return TRUE;
 
984
}
 
985
 
 
986
static Bool
 
987
vesaMapFramebuffer (KdScreenInfo    *screen)
 
988
{
 
989
    VesaCardPrivPtr     priv = screen->card->driver;
 
990
    VesaScreenPrivPtr   pscr = screen->driver;
 
991
 
 
992
    if (pscr->mapped)
 
993
        return TRUE;
 
994
    switch (pscr->mapping) {
 
995
    case VESA_MONO:
 
996
    case VESA_LINEAR:
 
997
        if (pscr->mode.vbe)
 
998
            pscr->fb = VbeMapFramebuffer(priv->vi, priv->vbeInfo, 
 
999
                                         pscr->mode.mode,
 
1000
                                         &pscr->fb_size,
 
1001
                                         &pscr->fb_phys);
 
1002
        else
 
1003
            pscr->fb = VgaMapFramebuffer (priv->vi, 
 
1004
                                          pscr->mode.mode,
 
1005
                                          &pscr->fb_size,
 
1006
                                          &pscr->fb_phys);
 
1007
        if (!pscr->fb)
 
1008
            return FALSE;
 
1009
        break;
 
1010
    case VESA_WINDOWED:
 
1011
        pscr->fb = NULL;
 
1012
        break;
 
1013
    case VESA_PLANAR:
 
1014
        pscr->fb = NULL;
 
1015
        break;
 
1016
    }
 
1017
    
 
1018
    screen->memory_base = pscr->fb;
 
1019
    screen->memory_size = pscr->fb_size;
 
1020
    
 
1021
    if (pscr->shadow)
 
1022
    {
 
1023
        if (!KdShadowFbAlloc (screen, 0, 
 
1024
                              pscr->randr & (RR_Rotate_90|RR_Rotate_270)))
 
1025
            return FALSE;
 
1026
        screen->off_screen_base = screen->memory_size;
 
1027
    }
 
1028
    else
 
1029
    {
 
1030
        screen->fb[0].frameBuffer = (CARD8 *) (pscr->fb);
 
1031
        screen->fb[0].byteStride = pscr->mode.BytesPerScanLine;
 
1032
        screen->fb[0].pixelStride = ((pscr->mode.BytesPerScanLine * 8) / 
 
1033
                                     screen->fb[0].bitsPerPixel);
 
1034
        screen->off_screen_base = screen->fb[0].byteStride * screen->height;
 
1035
    }
 
1036
    pscr->mapped = TRUE;
 
1037
    
 
1038
    return TRUE;
 
1039
}
 
1040
 
 
1041
static void
 
1042
vesaUnmapFramebuffer (KdScreenInfo  *screen)
 
1043
{
 
1044
    VesaCardPrivPtr         priv = screen->card->driver;
 
1045
    VesaScreenPrivPtr       pscr = screen->driver;
 
1046
    
 
1047
    if (!pscr->mapped)
 
1048
        return;
 
1049
    
 
1050
    pscr->mapped = FALSE;
 
1051
    KdShadowFbFree (screen, 0);
 
1052
    if (pscr->fb)
 
1053
    {
 
1054
        if (pscr->mode.vbe)
 
1055
            VbeUnmapFramebuffer(priv->vi, priv->vbeInfo, pscr->mode.mode, pscr->fb);
 
1056
        else
 
1057
            VgaUnmapFramebuffer (priv->vi);
 
1058
        pscr->fb = 0;
 
1059
    }
 
1060
}
 
1061
 
 
1062
#ifdef RANDR
 
1063
Bool
 
1064
vesaRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
 
1065
{
 
1066
    KdScreenPriv(pScreen);
 
1067
    VesaModePtr             modes, mode;
 
1068
    KdScreenInfo            *screen = pScreenPriv->screen;
 
1069
    VesaCardPrivPtr         priv = pScreenPriv->card->driver;
 
1070
    VesaScreenPrivPtr       pscr = pScreenPriv->screen->driver;
 
1071
    int                     nmode;
 
1072
    int                     n;
 
1073
    RRScreenSizePtr         pSize;
 
1074
    
 
1075
    *rotations = (RR_Rotate_0|RR_Rotate_90|RR_Rotate_180|RR_Rotate_270|
 
1076
                  RR_Reflect_X|RR_Reflect_Y);
 
1077
    /*
 
1078
     * Get mode information from BIOS -- every time in case
 
1079
     * something changes, like an external monitor is plugged in
 
1080
     */
 
1081
    modes = vesaGetModes (priv->vi, &nmode);
 
1082
    if (!modes)
 
1083
        return FALSE;
 
1084
    if (priv->modes)
 
1085
        xfree (priv->modes);
 
1086
    priv->modes = modes;
 
1087
    priv->nmode = nmode;
 
1088
    for (n = 0; n < nmode; n++)
 
1089
    {
 
1090
        mode = &priv->modes[n];
 
1091
        if (vesaModeSupported (priv, mode, FALSE))
 
1092
        {
 
1093
            /*
 
1094
             * XXX limit reported modes to those matching the current
 
1095
             * format
 
1096
             */
 
1097
            if (mode->NumberOfPlanes == pscr->mode.NumberOfPlanes &&
 
1098
                mode->BitsPerPixel == pscr->mode.BitsPerPixel &&
 
1099
                mode->MemoryModel == pscr->mode.MemoryModel &&
 
1100
                mode->RedMaskSize == pscr->mode.RedMaskSize &&
 
1101
                mode->RedFieldPosition == pscr->mode.RedFieldPosition &&
 
1102
                mode->GreenMaskSize == pscr->mode.GreenMaskSize &&
 
1103
                mode->GreenFieldPosition == pscr->mode.GreenFieldPosition &&
 
1104
                mode->BlueMaskSize == pscr->mode.BlueMaskSize &&
 
1105
                mode->BlueFieldPosition == pscr->mode.BlueFieldPosition)
 
1106
            {
 
1107
                int width, height, width_mm, height_mm;
 
1108
                if (screen->randr & (RR_Rotate_0|RR_Rotate_180))
 
1109
                {
 
1110
                    width = mode->XResolution;
 
1111
                    height = mode->YResolution;
 
1112
                    width_mm = screen->width_mm;
 
1113
                    height_mm = screen->height_mm;
 
1114
                }
 
1115
                else
 
1116
                {
 
1117
                    width = mode->YResolution;
 
1118
                    height = mode->XResolution;
 
1119
                    width_mm = screen->height_mm;
 
1120
                    height_mm = screen->width_mm;
 
1121
                }
 
1122
                pSize = RRRegisterSize (pScreen,
 
1123
                                        width, height,
 
1124
                                        width_mm, height_mm);
 
1125
                if (mode->XResolution == screen->width &&
 
1126
                    mode->YResolution == screen->height)
 
1127
                {
 
1128
                    int randr = KdSubRotation (pscr->randr, screen->randr);
 
1129
                    RRSetCurrentConfig (pScreen, randr, 0, pSize);
 
1130
                }
 
1131
            }
 
1132
        }
 
1133
    }
 
1134
    return TRUE;
 
1135
}
 
1136
 
 
1137
Bool
 
1138
vesaRandRSetConfig (ScreenPtr           pScreen,
 
1139
                    Rotation            randr,
 
1140
                    int                 rate,
 
1141
                    RRScreenSizePtr     pSize)
 
1142
{
 
1143
    KdScreenPriv(pScreen);
 
1144
    VesaModePtr         mode = 0;
 
1145
    KdScreenInfo        *screen = pScreenPriv->screen;
 
1146
    VesaCardPrivPtr     priv = pScreenPriv->card->driver;
 
1147
    VesaScreenPrivPtr   pscr = pScreenPriv->screen->driver;
 
1148
    int                 n;
 
1149
    Bool                wasEnabled = pScreenPriv->enabled;
 
1150
    Bool                ret = FALSE;
 
1151
    VesaScreenPrivRec   oldscr;
 
1152
    int                 oldwidth;
 
1153
    int                 oldheight;
 
1154
    int                 oldmmwidth;
 
1155
    int                 oldmmheight;
 
1156
    int                 newwidth, newheight;
 
1157
 
 
1158
    if (screen->randr & (RR_Rotate_0|RR_Rotate_180))
 
1159
    {
 
1160
        newwidth = pSize->width;
 
1161
        newheight = pSize->height;
 
1162
    }
 
1163
    else
 
1164
    {
 
1165
        newwidth = pSize->height;
 
1166
        newheight = pSize->width;
 
1167
    }
 
1168
    for (n = 0; n < priv->nmode; n++)
 
1169
    {
 
1170
        mode = &priv->modes[n];
 
1171
        if (vesaModeSupported (priv, mode, FALSE))
 
1172
        {
 
1173
            /* 
 
1174
             * XXX all we have to match is the size
 
1175
             */
 
1176
            if (mode->XResolution == newwidth &&
 
1177
                mode->YResolution == newheight &&
 
1178
                mode->NumberOfPlanes == pscr->mode.NumberOfPlanes &&
 
1179
                mode->BitsPerPixel == pscr->mode.BitsPerPixel &&
 
1180
                mode->RedMaskSize == pscr->mode.RedMaskSize &&
 
1181
                mode->RedFieldPosition == pscr->mode.RedFieldPosition &&
 
1182
                mode->GreenMaskSize == pscr->mode.GreenMaskSize &&
 
1183
                mode->GreenFieldPosition == pscr->mode.GreenFieldPosition &&
 
1184
                mode->BlueMaskSize == pscr->mode.BlueMaskSize &&
 
1185
                mode->BlueFieldPosition == pscr->mode.BlueFieldPosition)
 
1186
                break;
 
1187
        }
 
1188
    }
 
1189
    if (n == priv->nmode)
 
1190
        goto bail0;
 
1191
    
 
1192
    if (wasEnabled)
 
1193
        KdDisableScreen (pScreen);
 
1194
 
 
1195
    if (mode->mode != pscr->mode.mode)
 
1196
    {
 
1197
        ret = vesaSetMode (pScreen, mode);
 
1198
        if (!ret)
 
1199
            goto bail1;
 
1200
    }
 
1201
 
 
1202
    oldscr = *pscr;
 
1203
    
 
1204
    oldwidth = screen->width;
 
1205
    oldheight = screen->height;
 
1206
    oldmmwidth = pScreen->mmWidth;
 
1207
    oldmmheight = pScreen->mmHeight;
 
1208
    
 
1209
    /*
 
1210
     * Set new configuration
 
1211
     */
 
1212
    
 
1213
    pscr->mode = *mode;
 
1214
    pscr->randr = KdAddRotation (screen->randr, randr);
 
1215
                               
 
1216
    /*
 
1217
     * Can't rotate some formats
 
1218
     */
 
1219
    switch (screen->fb[0].bitsPerPixel) {
 
1220
    case 8:
 
1221
    case 16:
 
1222
    case 32:
 
1223
        break;
 
1224
    default:
 
1225
        if (pscr->randr)
 
1226
            goto bail2;
 
1227
        break;
 
1228
    }
 
1229
 
 
1230
    KdOffscreenSwapOut (screen->pScreen);
 
1231
    
 
1232
    vesaUnmapFramebuffer (screen);
 
1233
    
 
1234
    if (!vesaComputeFramebufferMapping (screen))
 
1235
        goto bail3;
 
1236
 
 
1237
    if (!vesaMapFramebuffer (screen))
 
1238
        goto bail3;
 
1239
    
 
1240
    vesaSetScreenSizes (screen->pScreen);
 
1241
    
 
1242
    if (!vesaSetShadow (screen->pScreen))
 
1243
        goto bail4;
 
1244
    
 
1245
    /*
 
1246
     * Set frame buffer mapping
 
1247
     */
 
1248
    (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
 
1249
                                    pScreen->width,
 
1250
                                    pScreen->height,
 
1251
                                    screen->fb[0].depth,
 
1252
                                    screen->fb[0].bitsPerPixel,
 
1253
                                    screen->fb[0].byteStride,
 
1254
                                    screen->fb[0].frameBuffer);
 
1255
    
 
1256
    /* set the subpixel order */
 
1257
    KdSetSubpixelOrder (pScreen, pscr->randr);
 
1258
 
 
1259
    if (wasEnabled)
 
1260
        KdEnableScreen (pScreen);
 
1261
 
 
1262
    return TRUE;
 
1263
 
 
1264
bail4:
 
1265
    vesaUnmapFramebuffer (screen);
 
1266
    *pscr = oldscr;
 
1267
    (void) vesaComputeFramebufferMapping (screen);
 
1268
    (void) vesaMapFramebuffer (screen);
 
1269
    
 
1270
bail3:
 
1271
    pScreen->width = oldwidth;
 
1272
    pScreen->height = oldheight;
 
1273
    pScreen->mmWidth = oldmmwidth;
 
1274
    pScreen->mmHeight = oldmmheight;
 
1275
    
 
1276
bail2:
 
1277
    *pscr = oldscr;
 
1278
    
 
1279
    (void) vesaSetMode (pScreen, &pscr->mode);
 
1280
bail1:
 
1281
    if (wasEnabled)
 
1282
        KdEnableScreen (pScreen);
 
1283
bail0:
 
1284
    
 
1285
    return FALSE;
 
1286
}
 
1287
 
 
1288
Bool
 
1289
vesaRandRInit (ScreenPtr pScreen)
 
1290
{
 
1291
    rrScrPrivPtr    pScrPriv;
 
1292
    
 
1293
    if (!RRScreenInit (pScreen))
 
1294
        return FALSE;
 
1295
 
 
1296
    pScrPriv = rrGetScrPriv(pScreen);
 
1297
    pScrPriv->rrGetInfo = vesaRandRGetInfo;
 
1298
    pScrPriv->rrSetConfig = vesaRandRSetConfig;
 
1299
    return TRUE;
 
1300
}
 
1301
#endif
 
1302
 
 
1303
Bool
 
1304
vesaInitScreen(ScreenPtr pScreen)
 
1305
{
 
1306
    KdScreenPriv(pScreen);
 
1307
    VesaScreenPrivPtr   pscr = pScreenPriv->screen->driver;
 
1308
    switch (pscr->mapping) {
 
1309
    case VESA_PLANAR:
 
1310
        pScreen->CreateColormap = vesaCreateColormap16;
 
1311
        break;
 
1312
    }
 
1313
    return TRUE;
 
1314
}
 
1315
 
 
1316
Bool
 
1317
vesaFinishInitScreen (ScreenPtr pScreen)
 
1318
{
 
1319
    if (!shadowSetup (pScreen))
 
1320
        return FALSE;
 
1321
    
 
1322
#ifdef RANDR
 
1323
    if (!vesaRandRInit (pScreen))
 
1324
        return FALSE;
 
1325
#endif
 
1326
    
 
1327
    return TRUE;
 
1328
}
 
1329
 
 
1330
Bool
 
1331
vesaCreateResources (ScreenPtr pScreen)
 
1332
{
 
1333
    return vesaSetShadow (pScreen);
 
1334
}
 
1335
 
 
1336
Bool
 
1337
vesaSetMode (ScreenPtr      pScreen,
 
1338
             VesaModePtr    mode)
 
1339
{
 
1340
    KdScreenPriv(pScreen);
 
1341
    VesaCardPrivPtr     priv = pScreenPriv->card->driver;
 
1342
    VesaScreenPrivPtr   pscr = pScreenPriv->screen->driver;
 
1343
    int                 code;
 
1344
    
 
1345
    if (mode->vbe)
 
1346
    {
 
1347
        if (vesa_verbose)
 
1348
            ErrorF ("Enable VBE mode 0x%x\n", mode->mode);
 
1349
        code = VbeSetMode(priv->vi, priv->vbeInfo, mode->mode,
 
1350
                          pscr->mapping == VESA_LINEAR,
 
1351
                          mode->MemoryModel == MEMORY_DIRECT);
 
1352
    }
 
1353
    else
 
1354
    {
 
1355
        if (vesa_verbose)
 
1356
            ErrorF ("Enable BIOS mode 0x%x\n", mode->mode);
 
1357
        code = VgaSetMode (priv->vi, mode->mode);
 
1358
    }
 
1359
    
 
1360
    if(code < 0)
 
1361
        return FALSE;
 
1362
    
 
1363
    return TRUE;
 
1364
}
 
1365
 
 
1366
Bool
 
1367
vesaEnable(ScreenPtr pScreen)
 
1368
{
 
1369
    KdScreenPriv(pScreen);
 
1370
    VesaCardPrivPtr     priv = pScreenPriv->card->driver;
 
1371
    VesaScreenPrivPtr   pscr = pScreenPriv->screen->driver;
 
1372
    KdScreenInfo        *screen = pScreenPriv->screen;
 
1373
    int                 i;
 
1374
    CARD32              size;
 
1375
    char                *p;
 
1376
    Bool                was_mapped = pscr->mapped;
 
1377
 
 
1378
    if (!vesaMapFramebuffer (screen))
 
1379
        return FALSE;
 
1380
 
 
1381
    if (!vesaSetMode (pScreen, &pscr->mode))
 
1382
        return FALSE;
 
1383
    
 
1384
    switch (pscr->mapping) {
 
1385
    case VESA_MONO:
 
1386
        VgaSetWritePlaneMask (priv->vi, 0x1);
 
1387
    case VESA_LINEAR:
 
1388
        if (vesa_restore_font)
 
1389
            memcpy (priv->text, pscr->fb, VESA_TEXT_SAVE);
 
1390
        break;
 
1391
    case VESA_WINDOWED:
 
1392
        if (vesa_restore_font)
 
1393
        {
 
1394
            for (i = 0; i < VESA_TEXT_SAVE;) 
 
1395
            {
 
1396
                p = vesaSetWindowWindowed (pScreen, 0, i, VBE_WINDOW_READ, &size);
 
1397
                if(!p) {
 
1398
                    ErrorF("Couldn't set window for saving VGA font\n");
 
1399
                    break;
 
1400
                }
 
1401
                if(i + size > VESA_TEXT_SAVE)
 
1402
                    size = VESA_TEXT_SAVE - i;
 
1403
                memcpy(((char*)priv->text) + i, p, size);
 
1404
                i += size;
 
1405
            }
 
1406
        }
 
1407
        break;
 
1408
    case VESA_PLANAR:
 
1409
        if (vesa_restore_font)
 
1410
        {
 
1411
            for (i = 0; i < 4; i++)
 
1412
            {
 
1413
                p = vesaSetWindowPlanar (pScreen, 0, i, VBE_WINDOW_READ, &size);
 
1414
                memcpy (((char *)priv->text) + i * (VESA_TEXT_SAVE/4), p,
 
1415
                        (VESA_TEXT_SAVE/4));
 
1416
            }
 
1417
        }
 
1418
        break;
 
1419
    }
 
1420
    if (!was_mapped)
 
1421
    {
 
1422
        (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
 
1423
                                        pScreen->width,
 
1424
                                        pScreen->height,
 
1425
                                        screen->fb[0].depth,
 
1426
                                        screen->fb[0].bitsPerPixel,
 
1427
                                        screen->fb[0].byteStride,
 
1428
                                        screen->fb[0].frameBuffer);
 
1429
    }
 
1430
    return TRUE;
 
1431
}
 
1432
 
 
1433
#ifndef TOSHIBA_SMM
 
1434
 
 
1435
# ifdef linux
 
1436
#  define TOSHIBA_SMM 1
 
1437
# endif
 
1438
 
 
1439
# ifndef TOSHIBA_SMM
 
1440
#  define TOSHIBA_SMM 0
 
1441
# endif
 
1442
 
 
1443
#endif
 
1444
 
 
1445
#if TOSHIBA_SMM
 
1446
/*
 
1447
 * Toshiba laptops use a special interface to operate the backlight
 
1448
 */
 
1449
#include <sys/ioctl.h>
 
1450
#define TOSH_PROC "/proc/toshiba"
 
1451
#define TOSH_DEVICE "/dev/toshiba"
 
1452
#define TOSH_SMM _IOWR('t', 0x90, SMMRegisters)
 
1453
 
 
1454
typedef struct {
 
1455
        unsigned int eax;
 
1456
        unsigned int ebx __attribute__ ((packed));
 
1457
        unsigned int ecx __attribute__ ((packed));
 
1458
        unsigned int edx __attribute__ ((packed));
 
1459
        unsigned int esi __attribute__ ((packed));
 
1460
        unsigned int edi __attribute__ ((packed));
 
1461
} SMMRegisters;
 
1462
 
 
1463
#define HCI_BACKLIGHT   0x0002
 
1464
#define HCI_DISABLE     0x0000
 
1465
#define HCI_ENABLE      0x0001
 
1466
#define HCI_GET         0xfe00,
 
1467
#define HCI_SET         0xff00
 
1468
 
 
1469
Bool
 
1470
toshibaDPMS (ScreenPtr pScreen, int mode)
 
1471
{
 
1472
    SMMRegisters    regs;
 
1473
    static int      fd;
 
1474
 
 
1475
    if (!fd)
 
1476
        fd = open (TOSH_DEVICE, 2);
 
1477
    if (fd < 0)
 
1478
        return FALSE;
 
1479
    regs.eax = HCI_SET;
 
1480
    regs.ebx = HCI_BACKLIGHT;
 
1481
    regs.ecx = mode ? HCI_DISABLE : HCI_ENABLE;
 
1482
    if (ioctl (fd, TOSH_SMM, &regs) < 0)
 
1483
        return FALSE;
 
1484
    return TRUE;
 
1485
}
 
1486
#endif /* TOSHIBA_SMM */
 
1487
 
 
1488
Bool
 
1489
vesaDPMS (ScreenPtr pScreen, int mode)
 
1490
{
 
1491
    KdScreenPriv(pScreen);
 
1492
    VesaCardPrivPtr     priv = pScreenPriv->card->driver;
 
1493
    VesaScreenPrivPtr   pscr = pScreenPriv->screen->driver;
 
1494
 
 
1495
#if TOSHIBA_SMM
 
1496
    if (toshibaDPMS (pScreen, mode))
 
1497
        return TRUE;
 
1498
#endif
 
1499
    if (pscr->mode.vbe)
 
1500
        return VbeDPMS (priv->vi, mode);
 
1501
    return FALSE;
 
1502
}
 
1503
 
 
1504
void
 
1505
vesaDisable(ScreenPtr pScreen)
 
1506
{
 
1507
    KdScreenPriv(pScreen);
 
1508
    KdScreenInfo        *screen = pScreenPriv->screen;
 
1509
    VesaCardPrivPtr     priv = pScreenPriv->card->driver;
 
1510
    VesaScreenPrivPtr   pscr = screen->driver;
 
1511
    int                 i=0;
 
1512
    CARD32              size;
 
1513
    char                *p;
 
1514
 
 
1515
    if (vesa_restore_font) {
 
1516
        switch (pscr->mapping) {
 
1517
        case VESA_LINEAR:
 
1518
        case VESA_MONO:
 
1519
            memcpy(pscr->fb, priv->text, VESA_TEXT_SAVE);
 
1520
            break;
 
1521
        case VESA_WINDOWED:
 
1522
            while(i < VESA_TEXT_SAVE) {
 
1523
                p = vesaSetWindowWindowed (pScreen, 0, i, VBE_WINDOW_WRITE, &size);
 
1524
                if(!p) {
 
1525
                    ErrorF("Couldn't set window for restoring VGA font\n");
 
1526
                    break;
 
1527
                }
 
1528
                if(i + size > VESA_TEXT_SAVE)
 
1529
                    size = VESA_TEXT_SAVE - i;
 
1530
                memcpy(p, ((char*)priv->text) + i, size);
 
1531
                i += size;
 
1532
            }
 
1533
            break;
 
1534
        case VESA_PLANAR:
 
1535
            for (i = 0; i < 4; i++)
 
1536
            {
 
1537
                p = vesaSetWindowPlanar (pScreen, 0, i, VBE_WINDOW_WRITE, &size);
 
1538
                memcpy (p,
 
1539
                        ((char *)priv->text) + i * (VESA_TEXT_SAVE/4),
 
1540
                        (VESA_TEXT_SAVE/4));
 
1541
            }
 
1542
            break;
 
1543
        }
 
1544
    }
 
1545
    vesaUnmapFramebuffer (screen);
 
1546
}
 
1547
 
 
1548
void
 
1549
vesaPreserve(KdCardInfo *card)
 
1550
{
 
1551
    VesaCardPrivPtr priv = card->driver;
 
1552
 
 
1553
    /* The framebuffer might not be valid at this point, so we cannot
 
1554
       save the VGA fonts now; we do it in vesaEnable. */
 
1555
 
 
1556
    if (VbeGetMode (priv->vi, &priv->old_vbe_mode) < 0)
 
1557
        priv->old_vbe_mode = -1;
 
1558
 
 
1559
    if (VgaGetMode (priv->vi, &priv->old_vga_mode) < 0)
 
1560
        priv->old_vga_mode = -1;
 
1561
    
 
1562
    if (vesa_verbose)
 
1563
        ErrorF ("Previous modes: VBE 0x%x BIOS 0x%x\n",
 
1564
                priv->old_vbe_mode, priv->old_vga_mode);
 
1565
}
 
1566
 
 
1567
void
 
1568
vesaRestore(KdCardInfo *card)
 
1569
{
 
1570
    VesaCardPrivPtr priv = card->driver;
 
1571
    int             n;
 
1572
 
 
1573
    if (vesa_force_text)
 
1574
    {
 
1575
        if (vesa_verbose)
 
1576
            ErrorF ("Forcing switch back to mode 3 text\n");
 
1577
        priv->old_vbe_mode = -1;
 
1578
        priv->old_vga_mode = 3;
 
1579
    }
 
1580
    for (n = 0; n < priv->nmode; n++)
 
1581
        if (priv->modes[n].vbe && priv->modes[n].mode == (priv->old_vbe_mode&0x3fff))
 
1582
            break;
 
1583
 
 
1584
    if (n < priv->nmode)
 
1585
    {
 
1586
        if (vesa_verbose)
 
1587
            ErrorF ("Restore VBE mode 0x%x\n", priv->old_vbe_mode);
 
1588
        VbeSetMode (priv->vi, priv->vbeInfo, priv->old_vbe_mode, 0, 0);
 
1589
    }
 
1590
    else
 
1591
    {
 
1592
        if (vesa_verbose)
 
1593
            ErrorF ("Restore BIOS mode 0x%x\n", priv->old_vga_mode);
 
1594
        VgaSetMode (priv->vi, priv->old_vga_mode);
 
1595
    }
 
1596
}
 
1597
 
 
1598
void
 
1599
vesaCardFini(KdCardInfo *card)
 
1600
{
 
1601
    VesaCardPrivPtr priv = card->driver;
 
1602
    
 
1603
    if (priv->vbeInfo)
 
1604
        VbeCleanup (priv->vi, priv->vbeInfo);
 
1605
    if (priv->modes)
 
1606
        xfree (priv->modes);
 
1607
    Vm86Cleanup(priv->vi);
 
1608
}
 
1609
 
 
1610
void 
 
1611
vesaScreenFini(KdScreenInfo *screen)
 
1612
{
 
1613
    VesaScreenPrivPtr   pscr = screen->driver;
 
1614
    
 
1615
    KdShadowFbFree (screen, 0);
 
1616
    vesaUnmapFramebuffer (screen);
 
1617
    screen->fb[0].depth = pscr->origDepth;
 
1618
}
 
1619
 
 
1620
int 
 
1621
vesaSetPalette(VesaCardPrivPtr priv, int first, int number, U8 *entries)
 
1622
{
 
1623
    if (priv->vga_palette)
 
1624
        return VgaSetPalette (priv->vi, first, number, entries);
 
1625
    else
 
1626
        return VbeSetPalette (priv->vi, priv->vbeInfo, first, number, entries);
 
1627
}
 
1628
    
 
1629
 
 
1630
int 
 
1631
vesaGetPalette(VesaCardPrivPtr priv, int first, int number, U8 *entries)
 
1632
{
 
1633
    int code;
 
1634
    
 
1635
    if (priv->vga_palette)
 
1636
        code = VgaGetPalette (priv->vi, first, number, entries);
 
1637
    else
 
1638
    {
 
1639
        code = VbeGetPalette (priv->vi, priv->vbeInfo, first, number, entries);
 
1640
        if (code < 0)
 
1641
        {
 
1642
            priv->vga_palette = 1;
 
1643
            code = VgaGetPalette (priv->vi, first, number, entries);
 
1644
        }
 
1645
    }
 
1646
    return code;
 
1647
}
 
1648
    
 
1649
void
 
1650
vesaPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
 
1651
{
 
1652
    KdScreenPriv(pScreen);
 
1653
    VesaScreenPrivPtr   pscr = pScreenPriv->screen->driver;
 
1654
    VesaCardPrivPtr     priv = pScreenPriv->card->driver;
 
1655
    int     p;
 
1656
    CARD8 *scratch;
 
1657
    int red, green, blue;
 
1658
    int min, max;
 
1659
 
 
1660
    if (vesa_swap_rgb)
 
1661
    {
 
1662
        red = 2;
 
1663
        green = 1;
 
1664
        blue = 0;
 
1665
    }
 
1666
    else
 
1667
    {
 
1668
        red = 0;
 
1669
        green = 1;
 
1670
        blue = 2;
 
1671
    }
 
1672
 
 
1673
    min = 256;
 
1674
    max = 0;
 
1675
    while (n--)
 
1676
    {
 
1677
        p = pdefs->pixel;
 
1678
        if (p < min)
 
1679
            min = p;
 
1680
        if (p > max)
 
1681
            max = p;
 
1682
        scratch = priv->cmap + (p * 4);
 
1683
        scratch[red] = pdefs->red >> 8;
 
1684
        scratch[green] = pdefs->green >> 8;
 
1685
        scratch[blue] = pdefs->blue >> 8;
 
1686
        scratch[3] = 0;
 
1687
        pdefs++;
 
1688
        if (pscr->mapping == VESA_PLANAR)
 
1689
        {
 
1690
            /*
 
1691
             * VGA modes are strange; this code covers all
 
1692
             * possible modes by duplicating the color information
 
1693
             * however the attribute registers might be set
 
1694
             */
 
1695
            if (p < 16)
 
1696
            {
 
1697
                vesaSetPalette (priv, p, 1, scratch);
 
1698
                if (p >= 8)
 
1699
                    vesaSetPalette (priv, p+0x30, 1, scratch);
 
1700
                else if (p == 6)
 
1701
                    vesaSetPalette (priv, 0x14, 1, scratch);
 
1702
            }
 
1703
        }
 
1704
    }
 
1705
    if (pscr->mapping != VESA_PLANAR)
 
1706
        vesaSetPalette (priv, min, max-min+1, priv->cmap + min * 4);
 
1707
}
 
1708
 
 
1709
void
 
1710
vesaGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
 
1711
{
 
1712
    KdScreenPriv(pScreen);
 
1713
    VesaScreenPrivPtr   pscr = pScreenPriv->screen->driver;
 
1714
    VesaCardPrivPtr priv = pScreenPriv->card->driver;
 
1715
    int i;
 
1716
    int red, green, blue;
 
1717
    int min, max;
 
1718
    int p;
 
1719
    CARD8 *scratch;
 
1720
 
 
1721
    if (vesa_swap_rgb)
 
1722
    {
 
1723
        red = 2;
 
1724
        green = 1;
 
1725
        blue = 0;
 
1726
    }
 
1727
    else
 
1728
    {
 
1729
        red = 0;
 
1730
        green = 1;
 
1731
        blue = 2;
 
1732
    }
 
1733
    
 
1734
    min = 256;
 
1735
    max = 0;
 
1736
    for(i = 0; i < n; i++) 
 
1737
    {
 
1738
        p = pdefs[i].pixel;
 
1739
        if (p < min)
 
1740
            min = p;
 
1741
        if (p > max)
 
1742
            max = p;
 
1743
        if (pscr->mapping == VESA_PLANAR)
 
1744
            vesaGetPalette (priv, p, 1, priv->cmap + p * 4);
 
1745
    }
 
1746
    if (pscr->mapping != VESA_PLANAR)
 
1747
        vesaGetPalette (priv, min, max - min + 1, priv->cmap + min * 4);
 
1748
    for (i = 0; i < n; i++)
 
1749
    {
 
1750
        p = pdefs[i].pixel;
 
1751
        scratch = priv->cmap + p * 4;
 
1752
        pdefs[i].red = scratch[red]<<8;
 
1753
        pdefs[i].green = scratch[green]<<8;
 
1754
        pdefs[i].blue = scratch[blue]<<8;
 
1755
    }
 
1756
}
 
1757
 
 
1758
void
 
1759
vesaUseMsg (void)
 
1760
{
 
1761
    ErrorF("\nTinyX VESA Usage:\n");
 
1762
    ErrorF("-mode         VESA video mode to use (Be careful!)\n");
 
1763
    ErrorF("-listmodes    List supported video modes\n");
 
1764
    ErrorF("-force        Attempt even unsupported modes\n");
 
1765
    ErrorF("-shadow       Always use shadow framebuffer (May increase performance)\n");
 
1766
    ErrorF("-nolinear     Never use linear framebuffer (Not useful)\n");
 
1767
    ErrorF("-swaprgb      Use if colors are wrong in PseudoColor and 16 color modes\n");
 
1768
    ErrorF("-map-holes    Use contiguous memory map (For seg fault with rare BIOS)\n");
 
1769
    ErrorF("-verbose      Emit diagnostic messages during BIOS initialization\n");
 
1770
    ErrorF("-force-text   Always use standard 25x80 text mode on server exit or VT switch\n");
 
1771
    ErrorF("-boot         Soft boot video card\n");
 
1772
    /* XXX: usage for -vesatest, -no-map-holes (don't need?),
 
1773
     * XXX: and -trash-font. Also in man page. */
 
1774
}
 
1775
 
 
1776
int
 
1777
vesaProcessArgument (int argc, char **argv, int i)
 
1778
{
 
1779
    if(!strcmp(argv[i], "-mode")) {
 
1780
        if(i+1 < argc) {
 
1781
            vesa_video_mode = strtol(argv[i+1], NULL, 0);
 
1782
        } else
 
1783
            UseMsg();
 
1784
        return 2;
 
1785
    } else if(!strcmp(argv[i], "-force")) {
 
1786
        vesa_force_mode = TRUE;
 
1787
        return 1;
 
1788
    } else if(!strcmp(argv[i], "-listmodes")) {
 
1789
        vesaListModes();
 
1790
        exit(0);
 
1791
    } else if(!strcmp(argv[i], "-vesatest")) {
 
1792
        vesaTestMode();
 
1793
        exit (0);
 
1794
    } else if(!strcmp(argv[i], "-swaprgb")) {
 
1795
        vesa_swap_rgb = TRUE;
 
1796
        return 1;
 
1797
    } else if(!strcmp(argv[i], "-shadow")) {
 
1798
        vesa_shadow = TRUE;
 
1799
        return 1;
 
1800
    } else if(!strcmp(argv[i], "-nolinear")) {
 
1801
        vesa_linear_fb = FALSE;
 
1802
        return 1;
 
1803
    } else if(!strcmp(argv[i], "-verbose")) {
 
1804
        vesa_verbose = TRUE;
 
1805
        return 1;
 
1806
    } else if(!strcmp(argv[i], "-force-text")) {
 
1807
        vesa_force_text = TRUE;
 
1808
        return 1;
 
1809
    } else if(!strcmp(argv[i], "-map-holes")) {
 
1810
        vesa_map_holes = TRUE;
 
1811
        return 1;
 
1812
    } else if(!strcmp(argv[i], "-no-map-holes")) {
 
1813
        vesa_map_holes = FALSE;
 
1814
        return 1;
 
1815
    } else if(!strcmp(argv[i], "-trash-font")) {
 
1816
        vesa_restore_font = FALSE;
 
1817
        return 1;
 
1818
    } else if(!strcmp(argv[i], "-boot")) {
 
1819
        vesa_boot = TRUE;
 
1820
        return 1;
 
1821
    }
 
1822
    
 
1823
    return 0;
 
1824
}