~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/hw/xfree86/vbe/vbe.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $XFree86: xc/programs/Xserver/hw/xfree86/vbe/vbe.c,v 1.1 2003/02/17 17:06:45 dawes Exp $ */
 
2
 
 
3
/*
 
4
 *                   XFree86 vbe module
 
5
 *               Copyright 2000 Egbert Eich
 
6
 *
 
7
 * The mode query/save/set/restore functions from the vesa driver 
 
8
 * have been moved here.
 
9
 * Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
 
10
 * Authors: Paulo C�sar Pereira de Andrade <pcpa@conectiva.com.br> 
 
11
 */
 
12
 
 
13
#include "xf86.h"
 
14
#include "xf86_ansic.h"
 
15
#include "vbe.h"
 
16
#include "Xarch.h"
 
17
#define DPMS_SERVER
 
18
#include "extensions/dpms.h"
 
19
 
 
20
#define VERSION(x) VBE_VERSION_MAJOR(x),VBE_VERSION_MINOR(x)
 
21
 
 
22
#if X_BYTE_ORDER == X_LITTLE_ENDIAN
 
23
#define B_O16(x)  (x) 
 
24
#define B_O32(x)  (x)
 
25
#else
 
26
#define B_O16(x)  ((((x) & 0xff) << 8) | (((x) & 0xff) >> 8))
 
27
#define B_O32(x)  ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) \
 
28
                  | (((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24))
 
29
#endif
 
30
#define L_ADD(x)  (B_O32(x) & 0xffff) + ((B_O32(x) >> 12) & 0xffff00)
 
31
 
 
32
#define FARP(p)         (((unsigned)(p & 0xffff0000) >> 12) | (p & 0xffff))
 
33
#define R16(v)          ((v) & 0xffff)
 
34
 
 
35
static unsigned char * vbeReadEDID(vbeInfoPtr pVbe);
 
36
static Bool vbeProbeDDC(vbeInfoPtr pVbe);
 
37
 
 
38
const char *vbe_ddcSymbols[] = {
 
39
    "xf86InterpretEDID",
 
40
    NULL
 
41
};
 
42
 
 
43
static const char vbeVersionString[] = "VBE2";
 
44
 
 
45
vbeInfoPtr
 
46
VBEInit(xf86Int10InfoPtr pInt, int entityIndex)
 
47
{
 
48
    return VBEExtendedInit(pInt, entityIndex, 0);
 
49
}
 
50
 
 
51
vbeInfoPtr
 
52
VBEExtendedInit(xf86Int10InfoPtr pInt, int entityIndex, int Flags)
 
53
{
 
54
    int RealOff;
 
55
    pointer page = NULL;
 
56
    ScrnInfoPtr pScrn = xf86FindScreenForEntity(entityIndex);
 
57
    vbeControllerInfoPtr vbe = NULL;
 
58
    Bool init_int10 = FALSE;
 
59
    vbeInfoPtr vip = NULL;
 
60
    int screen = pScrn->scrnIndex;
 
61
 
 
62
    if (!pInt) {
 
63
        if (!xf86LoadSubModule(pScrn, "int10"))
 
64
            goto error;
 
65
 
 
66
        xf86DrvMsg(screen,X_INFO,"initializing int10\n");
 
67
        pInt = xf86InitInt10(entityIndex);
 
68
        if (!pInt)
 
69
            goto error;
 
70
        init_int10 = TRUE;
 
71
    }
 
72
    
 
73
    page = xf86Int10AllocPages(pInt,1,&RealOff);
 
74
    if (!page) goto error;
 
75
    vbe = (vbeControllerInfoPtr) page;    
 
76
    memcpy(vbe->VbeSignature,vbeVersionString,4);
 
77
 
 
78
    pInt->ax = 0x4F00;
 
79
    pInt->es = SEG_ADDR(RealOff);
 
80
    pInt->di = SEG_OFF(RealOff);
 
81
    pInt->num = 0x10;
 
82
    
 
83
    xf86ExecX86int10(pInt);
 
84
 
 
85
    if ((pInt->ax & 0xff) != 0x4f) {
 
86
        xf86DrvMsgVerb(screen,X_INFO,3,"VESA BIOS not detected\n");
 
87
        goto error;
 
88
    }
 
89
    
 
90
    switch (pInt->ax & 0xff00) {
 
91
    case 0:
 
92
        xf86DrvMsg(screen,X_INFO,"VESA BIOS detected\n");
 
93
        break;
 
94
    case 0x100:
 
95
        xf86DrvMsg(screen,X_INFO,"VESA BIOS function failed\n");
 
96
        goto error;
 
97
    case 0x200:
 
98
        xf86DrvMsg(screen,X_INFO,"VESA BIOS not supported\n");
 
99
        goto error;
 
100
    case 0x300:
 
101
        xf86DrvMsg(screen,X_INFO,"VESA BIOS not supported in current mode\n");
 
102
        goto error;
 
103
    default:
 
104
        xf86DrvMsg(screen,X_INFO,"Invalid\n");
 
105
        goto error;
 
106
    }
 
107
    
 
108
    xf86DrvMsgVerb(screen, X_INFO, 4,
 
109
                "VbeVersion is %d, OemStringPtr is 0x%08x,\n"
 
110
                "\tOemVendorNamePtr is 0x%08x, OemProductNamePtr is 0x%08x,\n"
 
111
                "\tOemProductRevPtr is 0x%08x\n",
 
112
                vbe->VbeVersion, vbe->OemStringPtr, vbe->OemVendorNamePtr,
 
113
                vbe->OemProductNamePtr, vbe->OemProductRevPtr);
 
114
 
 
115
    xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE Version %i.%i\n",
 
116
                   VERSION(vbe->VbeVersion));
 
117
    xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE Total Mem: %i kB\n",
 
118
                   vbe->TotalMem * 64);
 
119
    xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM: %s\n",
 
120
                   (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemStringPtr)));
 
121
    
 
122
    if (B_O16(vbe->VbeVersion) >= 0x200) {
 
123
        xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Software Rev: %i.%i\n",
 
124
                    VERSION(vbe->OemSoftwareRev));
 
125
        if (vbe->OemVendorNamePtr)
 
126
            xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Vendor: %s\n",
 
127
                    (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemVendorNamePtr)));
 
128
        if (vbe->OemProductNamePtr)
 
129
            xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Product: %s\n",
 
130
                    (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemProductNamePtr)));
 
131
        if (vbe->OemProductRevPtr)
 
132
            xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Product Rev: %s\n",
 
133
                    (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemProductRevPtr)));
 
134
    }
 
135
    vip = (vbeInfoPtr)xnfalloc(sizeof(vbeInfoRec));
 
136
    vip->version = B_O16(vbe->VbeVersion);
 
137
    vip->pInt10 = pInt;
 
138
    vip->ddc = DDC_UNCHECKED;
 
139
    vip->memory = page;
 
140
    vip->real_mode_base = RealOff;
 
141
    vip->num_pages = 1;
 
142
    vip->init_int10 = init_int10;
 
143
 
 
144
    return vip;
 
145
 
 
146
 error:
 
147
    if (page)
 
148
        xf86Int10FreePages(pInt, page, 1);
 
149
    if (init_int10)
 
150
        xf86FreeInt10(pInt);
 
151
    return NULL;
 
152
}
 
153
 
 
154
void
 
155
vbeFree(vbeInfoPtr pVbe)
 
156
{
 
157
    if (!pVbe)
 
158
        return;
 
159
 
 
160
    xf86Int10FreePages(pVbe->pInt10,pVbe->memory,pVbe->num_pages);
 
161
    /* If we have initalized int10 we ought to free it, too */
 
162
    if (pVbe->init_int10) 
 
163
        xf86FreeInt10(pVbe->pInt10);
 
164
    xfree(pVbe);
 
165
    return;
 
166
}
 
167
 
 
168
static Bool
 
169
vbeProbeDDC(vbeInfoPtr pVbe)
 
170
{
 
171
    char *ddc_level;
 
172
    int screen = pVbe->pInt10->scrnIndex;
 
173
    
 
174
    if (!pVbe || (pVbe->ddc == DDC_NONE))
 
175
        return FALSE;
 
176
    if (pVbe->ddc != DDC_UNCHECKED)
 
177
        return TRUE;
 
178
 
 
179
    pVbe->pInt10->ax = 0x4F15;
 
180
    pVbe->pInt10->bx = 0;
 
181
    pVbe->pInt10->cx = 0;
 
182
    pVbe->pInt10->es = 0;
 
183
    pVbe->pInt10->di = 0;
 
184
    pVbe->pInt10->num = 0x10;
 
185
 
 
186
    xf86ExecX86int10(pVbe->pInt10);
 
187
 
 
188
    if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
 
189
        xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC not supported\n");
 
190
        pVbe->ddc = DDC_NONE;
 
191
        return FALSE;
 
192
    }
 
193
 
 
194
    switch ((pVbe->pInt10->ax >> 8) & 0xff) {
 
195
    case 0:
 
196
        xf86DrvMsg(screen,X_INFO,"VESA VBE DDC supported\n");
 
197
        switch (pVbe->pInt10->bx & 0x3) {
 
198
        case 0:
 
199
            ddc_level = " none"; 
 
200
            pVbe->ddc = DDC_NONE;
 
201
            break;
 
202
        case 1:
 
203
            ddc_level = " 1";
 
204
            pVbe->ddc = DDC_1;
 
205
            break;
 
206
        case 2:
 
207
            ddc_level = " 2"; 
 
208
            pVbe->ddc = DDC_2;
 
209
            break;
 
210
        case 3:
 
211
            ddc_level = " 1 + 2"; 
 
212
            pVbe->ddc = DDC_1_2;
 
213
            break;
 
214
        default:
 
215
            ddc_level = "";
 
216
            pVbe->ddc = DDC_NONE;
 
217
            break;
 
218
        }
 
219
        xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC Level%s\n",ddc_level); 
 
220
        if (pVbe->pInt10->bx & 0x4) {
 
221
            xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC Screen blanked" 
 
222
                        "for data transfer\n"); 
 
223
            pVbe->ddc_blank = TRUE;
 
224
        }  else
 
225
            pVbe->ddc_blank = FALSE;
 
226
            
 
227
        xf86DrvMsgVerb(screen,X_INFO,3,
 
228
                       "VESA VBE DDC transfer in appr. %x sec.\n", 
 
229
                       (pVbe->pInt10->bx >> 8) & 0xff); 
 
230
    }
 
231
    
 
232
    return TRUE; 
 
233
}
 
234
 
 
235
typedef enum {
 
236
  VBEOPT_NOVBE,
 
237
    VBEOPT_NODDC
 
238
} VBEOpts;
 
239
 
 
240
static const OptionInfoRec VBEOptions[] = {
 
241
    { VBEOPT_NOVBE,     "NoVBE",        OPTV_BOOLEAN,   {0},    FALSE },
 
242
    { VBEOPT_NODDC,     "NoDDC",        OPTV_BOOLEAN,   {0},    FALSE },
 
243
    { -1,               NULL,           OPTV_NONE,      {0},    FALSE },
 
244
};
 
245
 
 
246
static unsigned char *
 
247
vbeReadEDID(vbeInfoPtr pVbe)
 
248
{
 
249
    int RealOff = pVbe->real_mode_base;
 
250
    pointer page = pVbe->memory;
 
251
    unsigned char *tmp = NULL;
 
252
    Bool novbe = FALSE;
 
253
    Bool noddc = FALSE;
 
254
    int screen = pVbe->pInt10->scrnIndex;
 
255
    OptionInfoPtr options;
 
256
 
 
257
    if (!page) return NULL;
 
258
 
 
259
    options = xnfalloc(sizeof(VBEOptions));
 
260
    (void)memcpy(options, VBEOptions, sizeof(VBEOptions));
 
261
    xf86ProcessOptions(screen, xf86Screens[screen]->options, options);
 
262
    xf86GetOptValBool(options, VBEOPT_NOVBE, &novbe);
 
263
    xf86GetOptValBool(options, VBEOPT_NODDC, &noddc);
 
264
    xfree(options);
 
265
    if (novbe || noddc) return NULL;
 
266
    
 
267
    if (!vbeProbeDDC(pVbe)) goto error;
 
268
 
 
269
    memset(page,0,sizeof(vbeInfoPtr));
 
270
    strcpy(page,vbeVersionString);
 
271
 
 
272
    pVbe->pInt10->ax = 0x4F15;
 
273
    pVbe->pInt10->bx = 0x01;
 
274
    pVbe->pInt10->cx = 0;
 
275
    pVbe->pInt10->dx = 0;
 
276
    pVbe->pInt10->es = SEG_ADDR(RealOff);
 
277
    pVbe->pInt10->di = SEG_OFF(RealOff);
 
278
    pVbe->pInt10->num = 0x10;
 
279
 
 
280
    xf86ExecX86int10(pVbe->pInt10);
 
281
 
 
282
    if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
 
283
        xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC invalid\n");
 
284
        goto error;
 
285
    }
 
286
    switch (pVbe->pInt10->ax & 0xff00) {
 
287
    case 0x0:
 
288
        xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC read successfully\n");
 
289
        tmp = (unsigned char *)xnfalloc(128); 
 
290
        memcpy(tmp,page,128); 
 
291
        break;
 
292
    case 0x100:
 
293
        xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC read failed\n");   
 
294
        break;
 
295
    default:
 
296
        xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC unkown failure %i\n",
 
297
                       pVbe->pInt10->ax & 0xff00);
 
298
        break;
 
299
    }
 
300
    
 
301
 error:
 
302
    return tmp;
 
303
}
 
304
 
 
305
xf86MonPtr
 
306
vbeDoEDID(vbeInfoPtr pVbe, pointer pDDCModule)
 
307
{
 
308
    xf86MonPtr    pMonitor;
 
309
    pointer       pModule;
 
310
    unsigned char *DDC_data = NULL;
 
311
    
 
312
    if (!pVbe) return NULL;
 
313
    if (pVbe->version < 0x200)
 
314
        return NULL;
 
315
 
 
316
    if (!(pModule = pDDCModule)) {
 
317
        pModule =
 
318
            xf86LoadSubModule(xf86Screens[pVbe->pInt10->scrnIndex], "ddc");
 
319
        if (!pModule)
 
320
            return NULL;
 
321
 
 
322
        xf86LoaderReqSymLists(vbe_ddcSymbols, NULL);
 
323
    }
 
324
        
 
325
    DDC_data = vbeReadEDID(pVbe);
 
326
 
 
327
    if (!DDC_data) 
 
328
        return NULL;
 
329
    
 
330
    pMonitor = xf86InterpretEDID(pVbe->pInt10->scrnIndex, DDC_data);
 
331
 
 
332
    if (!pDDCModule)
 
333
        xf86UnloadSubModule(pModule);
 
334
    return pMonitor;
 
335
}
 
336
 
 
337
 
 
338
VbeInfoBlock *
 
339
VBEGetVBEInfo(vbeInfoPtr pVbe)
 
340
{
 
341
    VbeInfoBlock *block = NULL;
 
342
    int i, pStr, pModes;
 
343
    char *str;
 
344
    CARD16 major, minor, *modes;
 
345
 
 
346
    bzero(pVbe->memory, sizeof(VbeInfoBlock));
 
347
 
 
348
    /*
 
349
    Input:
 
350
        AH    := 4Fh    Super VGA support
 
351
        AL    := 00h    Return Super VGA information
 
352
        ES:DI := Pointer to buffer
 
353
 
 
354
    Output:
 
355
        AX    := status
 
356
        (All other registers are preserved)
 
357
     */
 
358
 
 
359
    ((char*)pVbe->memory)[0] = 'V';
 
360
    ((char*)pVbe->memory)[1] = 'B';
 
361
    ((char*)pVbe->memory)[2] = 'E';
 
362
    ((char*)pVbe->memory)[3] = '2';
 
363
 
 
364
    pVbe->pInt10->num = 0x10;
 
365
    pVbe->pInt10->ax = 0x4f00;
 
366
    pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
 
367
    pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
 
368
    xf86ExecX86int10(pVbe->pInt10);
 
369
 
 
370
    if (R16(pVbe->pInt10->ax) != 0x4f)
 
371
        return (NULL);
 
372
 
 
373
    block = xcalloc(sizeof(VbeInfoBlock), 1);
 
374
    block->VESASignature[0] = ((char*)pVbe->memory)[0];
 
375
    block->VESASignature[1] = ((char*)pVbe->memory)[1];
 
376
    block->VESASignature[2] = ((char*)pVbe->memory)[2];
 
377
    block->VESASignature[3] = ((char*)pVbe->memory)[3];
 
378
 
 
379
    block->VESAVersion = *(CARD16*)(((char*)pVbe->memory) + 4);
 
380
    major = (unsigned)block->VESAVersion >> 8;
 
381
    minor = block->VESAVersion & 0xff;
 
382
 
 
383
    pStr = *(CARD32*)(((char*)pVbe->memory) + 6);
 
384
    str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
 
385
    block->OEMStringPtr = strdup(str);
 
386
 
 
387
    block->Capabilities[0] = ((char*)pVbe->memory)[10];
 
388
    block->Capabilities[1] = ((char*)pVbe->memory)[11];
 
389
    block->Capabilities[2] = ((char*)pVbe->memory)[12];
 
390
    block->Capabilities[3] = ((char*)pVbe->memory)[13];
 
391
 
 
392
    pModes = *(CARD32*)(((char*)pVbe->memory) + 14);
 
393
    modes = xf86int10Addr(pVbe->pInt10, FARP(pModes));
 
394
    i = 0;
 
395
    while (modes[i] != 0xffff)
 
396
        i++;
 
397
    block->VideoModePtr = xalloc(sizeof(CARD16) * i + 1);
 
398
    memcpy(block->VideoModePtr, modes, sizeof(CARD16) * i);
 
399
    block->VideoModePtr[i] = 0xffff;
 
400
 
 
401
    block->TotalMemory = *(CARD16*)(((char*)pVbe->memory) + 18);
 
402
 
 
403
    if (major < 2)
 
404
        memcpy(&block->OemSoftwareRev, ((char*)pVbe->memory) + 20, 236);
 
405
    else {
 
406
        block->OemSoftwareRev = *(CARD16*)(((char*)pVbe->memory) + 20);
 
407
        pStr = *(CARD32*)(((char*)pVbe->memory) + 22);
 
408
        str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
 
409
        block->OemVendorNamePtr = strdup(str);
 
410
        pStr = *(CARD32*)(((char*)pVbe->memory) + 26);
 
411
        str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
 
412
        block->OemProductNamePtr = strdup(str);
 
413
        pStr = *(CARD32*)(((char*)pVbe->memory) + 30);
 
414
        str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
 
415
        block->OemProductRevPtr = strdup(str);
 
416
        memcpy(&block->Reserved, ((char*)pVbe->memory) + 34, 222);
 
417
        memcpy(&block->OemData, ((char*)pVbe->memory) + 256, 256);
 
418
    }
 
419
 
 
420
    return (block);
 
421
}
 
422
 
 
423
void
 
424
VBEFreeVBEInfo(VbeInfoBlock *block)
 
425
{
 
426
    xfree(block->OEMStringPtr);
 
427
    xfree(block->VideoModePtr);
 
428
    if (((unsigned)block->VESAVersion >> 8) >= 2) {
 
429
        xfree(block->OemVendorNamePtr);
 
430
        xfree(block->OemProductNamePtr);
 
431
        xfree(block->OemProductRevPtr);
 
432
    }
 
433
    xfree(block);
 
434
}
 
435
 
 
436
Bool
 
437
VBESetVBEMode(vbeInfoPtr pVbe, int mode, VbeCRTCInfoBlock *block)
 
438
{
 
439
    /*
 
440
    Input:
 
441
        AH    := 4Fh    Super VGA support
 
442
        AL    := 02h    Set Super VGA video mode
 
443
        BX    := Video mode
 
444
            D0-D8  := Mode number
 
445
            D9-D10 := Reserved (must be 0)
 
446
            D11    := 0 Use current default refresh rate
 
447
                   := 1 Use user specified CRTC values for refresh rate
 
448
            D12-13      Reserved for VBE/AF (must be 0)
 
449
            D14    := 0 Use windowed frame buffer model
 
450
                   := 1 Use linear/flat frame buffer model
 
451
            D15    := 0 Clear video memory
 
452
                   := 1 Don't clear video memory
 
453
        ES:DI := Pointer to VbeCRTCInfoBlock structure
 
454
 
 
455
    Output: AX = Status
 
456
        (All other registers are preserved)
 
457
    */
 
458
    pVbe->pInt10->num = 0x10;
 
459
    pVbe->pInt10->ax = 0x4f02;
 
460
    pVbe->pInt10->bx = mode;
 
461
    if (block) {
 
462
        pVbe->pInt10->bx |= 1 << 11;
 
463
        memcpy(pVbe->memory, block, sizeof(VbeCRTCInfoBlock));
 
464
        pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
 
465
        pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
 
466
    }
 
467
 
 
468
    xf86ExecX86int10(pVbe->pInt10);
 
469
 
 
470
    return (R16(pVbe->pInt10->ax) == 0x4f);
 
471
}
 
472
 
 
473
Bool
 
474
VBEGetVBEMode(vbeInfoPtr pVbe, int *mode)
 
475
{
 
476
    /*
 
477
    Input:
 
478
        AH := 4Fh       Super VGA support
 
479
        AL := 03h       Return current video mode
 
480
 
 
481
    Output:
 
482
        AX := Status
 
483
        BX := Current video mode
 
484
        (All other registers are preserved)
 
485
    */
 
486
    pVbe->pInt10->num = 0x10;
 
487
    pVbe->pInt10->ax = 0x4f03;
 
488
 
 
489
    xf86ExecX86int10(pVbe->pInt10);
 
490
 
 
491
    if (R16(pVbe->pInt10->ax) == 0x4f) {
 
492
        *mode = R16(pVbe->pInt10->bx);
 
493
 
 
494
        return (TRUE);
 
495
    }
 
496
 
 
497
    return (FALSE);
 
498
}
 
499
 
 
500
VbeModeInfoBlock *
 
501
VBEGetModeInfo(vbeInfoPtr pVbe, int mode)
 
502
{
 
503
    VbeModeInfoBlock *block = NULL;
 
504
 
 
505
    bzero(pVbe->memory, sizeof(VbeModeInfoBlock));
 
506
 
 
507
    /*
 
508
    Input:
 
509
        AH    := 4Fh    Super VGA support
 
510
        AL    := 01h    Return Super VGA mode information
 
511
        CX    :=        Super VGA video mode
 
512
                        (mode number must be one of those returned by Function 0)
 
513
        ES:DI := Pointer to buffer
 
514
 
 
515
    Output:
 
516
        AX    := status
 
517
        (All other registers are preserved)
 
518
     */
 
519
    pVbe->pInt10->num = 0x10;
 
520
    pVbe->pInt10->ax = 0x4f01;
 
521
    pVbe->pInt10->cx = mode;
 
522
    pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
 
523
    pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
 
524
    xf86ExecX86int10(pVbe->pInt10);
 
525
    if (R16(pVbe->pInt10->ax) != 0x4f)
 
526
        return (NULL);
 
527
 
 
528
    block = xcalloc(sizeof(VbeModeInfoBlock), 1);
 
529
 
 
530
    block->ModeAttributes = *(CARD16*)pVbe->memory;
 
531
    block->WinAAttributes = ((char*)pVbe->memory)[2];
 
532
    block->WinBAttributes = ((char*)pVbe->memory)[3];
 
533
    block->WinGranularity = *(CARD16*)(((char*)pVbe->memory) + 4);
 
534
    block->WinSize = *(CARD16*)(((char*)pVbe->memory) + 6);
 
535
    block->WinASegment = *(CARD16*)(((char*)pVbe->memory) + 8);
 
536
    block->WinBSegment = *(CARD16*)(((char*)pVbe->memory) + 10);
 
537
    block->WinFuncPtr = *(CARD32*)(((char*)pVbe->memory) + 12);
 
538
    block->BytesPerScanline = *(CARD16*)(((char*)pVbe->memory) + 16);
 
539
 
 
540
    /* mandatory information for VBE 1.2 and above */
 
541
    block->XResolution = *(CARD16*)(((char*)pVbe->memory) + 18);
 
542
    block->YResolution = *(CARD16*)(((char*)pVbe->memory) + 20);
 
543
    block->XCharSize = ((char*)pVbe->memory)[22];
 
544
    block->YCharSize = ((char*)pVbe->memory)[23];
 
545
    block->NumberOfPlanes = ((char*)pVbe->memory)[24];
 
546
    block->BitsPerPixel = ((char*)pVbe->memory)[25];
 
547
    block->NumberOfBanks = ((char*)pVbe->memory)[26];
 
548
    block->MemoryModel = ((char*)pVbe->memory)[27];
 
549
    block->BankSize = ((char*)pVbe->memory)[28];
 
550
    block->NumberOfImages = ((char*)pVbe->memory)[29];
 
551
    block->Reserved = ((char*)pVbe->memory)[30];
 
552
 
 
553
    /* Direct color fields (required for direct/6 and YUV/7 memory models) */
 
554
    block->RedMaskSize = ((char*)pVbe->memory)[31];
 
555
    block->RedFieldPosition = ((char*)pVbe->memory)[32];
 
556
    block->GreenMaskSize = ((char*)pVbe->memory)[33];
 
557
    block->GreenFieldPosition = ((char*)pVbe->memory)[34];
 
558
    block->BlueMaskSize = ((char*)pVbe->memory)[35];
 
559
    block->BlueFieldPosition = ((char*)pVbe->memory)[36];
 
560
    block->RsvdMaskSize = ((char*)pVbe->memory)[37];
 
561
    block->RsvdFieldPosition = ((char*)pVbe->memory)[38];
 
562
    block->DirectColorModeInfo = ((char*)pVbe->memory)[39];
 
563
 
 
564
    /* Mandatory information for VBE 2.0 and above */
 
565
    if (pVbe->version >= 0x200) {
 
566
        block->PhysBasePtr = *(CARD32*)(((char*)pVbe->memory) + 40);
 
567
        block->Reserved32 = *(CARD32*)(((char*)pVbe->memory) + 44);
 
568
        block->Reserved16 = *(CARD16*)(((char*)pVbe->memory) + 48);
 
569
 
 
570
        /* Mandatory information for VBE 3.0 and above */
 
571
        if (pVbe->version >= 0x300) {
 
572
            block->LinBytesPerScanLine = *(CARD16*)(((char*)pVbe->memory) + 50);
 
573
            block->BnkNumberOfImagePages = ((char*)pVbe->memory)[52];
 
574
            block->LinNumberOfImagePages = ((char*)pVbe->memory)[53];
 
575
            block->LinRedMaskSize = ((char*)pVbe->memory)[54];
 
576
            block->LinRedFieldPosition = ((char*)pVbe->memory)[55];
 
577
            block->LinGreenMaskSize = ((char*)pVbe->memory)[56];
 
578
            block->LinGreenFieldPosition = ((char*)pVbe->memory)[57];
 
579
            block->LinBlueMaskSize = ((char*)pVbe->memory)[58];
 
580
            block->LinBlueFieldPosition = ((char*)pVbe->memory)[59];
 
581
            block->LinRsvdMaskSize = ((char*)pVbe->memory)[60];
 
582
            block->LinRsvdFieldPosition = ((char*)pVbe->memory)[61];
 
583
            block->MaxPixelClock = *(CARD32*)(((char*)pVbe->memory) + 62);
 
584
            memcpy(&block->Reserved2, ((char*)pVbe->memory) + 66, 188);
 
585
        }
 
586
        else
 
587
        memcpy(&block->LinBytesPerScanLine, ((char*)pVbe->memory) + 50, 206);
 
588
    }
 
589
    else
 
590
        memcpy(&block->PhysBasePtr, ((char*)pVbe->memory) + 40, 216);
 
591
 
 
592
    return (block);
 
593
}
 
594
 
 
595
void
 
596
VBEFreeModeInfo(VbeModeInfoBlock *block)
 
597
{
 
598
    xfree(block);
 
599
}
 
600
 
 
601
Bool
 
602
VBESaveRestore(vbeInfoPtr pVbe, vbeSaveRestoreFunction function, 
 
603
               pointer *memory, int *size, int *real_mode_pages)
 
604
{
 
605
    /*
 
606
    Input:
 
607
        AH    := 4Fh    Super VGA support
 
608
        AL    := 04h    Save/restore Super VGA video state
 
609
        DL    := 00h    Return save/restore state buffer size
 
610
        CX    := Requested states
 
611
                D0 = Save/restore video hardware state
 
612
                D1 = Save/restore video BIOS data state
 
613
                D2 = Save/restore video DAC state
 
614
                D3 = Save/restore Super VGA state
 
615
 
 
616
    Output:
 
617
        AX = Status
 
618
        BX = Number of 64-byte blocks to hold the state buffer
 
619
        (All other registers are preserved)
 
620
 
 
621
 
 
622
    Input:
 
623
        AH    := 4Fh    Super VGA support
 
624
        AL    := 04h    Save/restore Super VGA video state
 
625
        DL    := 01h    Save Super VGA video state
 
626
        CX    := Requested states (see above)
 
627
        ES:BX := Pointer to buffer
 
628
 
 
629
    Output:
 
630
        AX    := Status
 
631
        (All other registers are preserved)
 
632
 
 
633
 
 
634
    Input:
 
635
        AH    := 4Fh    Super VGA support
 
636
        AL    := 04h    Save/restore Super VGA video state
 
637
        DL    := 02h    Restore Super VGA video state
 
638
        CX    := Requested states (see above)
 
639
        ES:BX := Pointer to buffer
 
640
 
 
641
    Output:
 
642
        AX     := Status
 
643
        (All other registers are preserved)
 
644
     */
 
645
 
 
646
    if ((pVbe->version & 0xff00) > 0x100) {
 
647
        int screen = pVbe->pInt10->scrnIndex;
 
648
        if (function == MODE_QUERY ||
 
649
            (function == MODE_SAVE && !*memory)) {
 
650
            /* Query amount of memory to save state */
 
651
 
 
652
            pVbe->pInt10->num = 0x10;
 
653
            pVbe->pInt10->ax = 0x4f04;
 
654
            pVbe->pInt10->dx = 0;
 
655
            pVbe->pInt10->cx = 0x000f;
 
656
            xf86ExecX86int10(pVbe->pInt10);
 
657
            if (R16(pVbe->pInt10->ax) != 0x4f)
 
658
                return (FALSE);
 
659
 
 
660
            if (function == MODE_SAVE) {
 
661
                int npages = (R16(pVbe->pInt10->bx) * 64) / 4096 + 1;
 
662
                if ((*memory = xf86Int10AllocPages(pVbe->pInt10, npages,
 
663
                                                   real_mode_pages)) == NULL) {
 
664
                    xf86DrvMsg(screen, X_ERROR,
 
665
                               "Cannot allocate memory to save SVGA state.\n");
 
666
                    return (FALSE);
 
667
                }
 
668
            }
 
669
            *size = pVbe->pInt10->bx * 64;
 
670
        }
 
671
 
 
672
        /* Save/Restore Super VGA state */
 
673
        if (function != MODE_QUERY) {
 
674
            
 
675
            if (!*memory) return FALSE;
 
676
            pVbe->pInt10->num = 0x10;
 
677
            pVbe->pInt10->ax = 0x4f04;
 
678
            switch (function) {
 
679
            case MODE_SAVE:
 
680
              pVbe->pInt10->dx = 1;
 
681
              break;
 
682
            case MODE_RESTORE:
 
683
              pVbe->pInt10->dx = 2;
 
684
              break;
 
685
            case MODE_QUERY:
 
686
              return FALSE;
 
687
            }
 
688
            pVbe->pInt10->cx = 0x000f;
 
689
            
 
690
            pVbe->pInt10->es = SEG_ADDR(*real_mode_pages);
 
691
            pVbe->pInt10->bx = SEG_OFF(*real_mode_pages);
 
692
            xf86ExecX86int10(pVbe->pInt10);
 
693
            return (R16(pVbe->pInt10->ax) == 0x4f);
 
694
 
 
695
        }
 
696
    }
 
697
    return TRUE;
 
698
}
 
699
 
 
700
Bool
 
701
VBEBankSwitch(vbeInfoPtr pVbe, unsigned int iBank, int window)
 
702
{
 
703
    /*
 
704
    Input:
 
705
        AH    := 4Fh    Super VGA support
 
706
        AL    := 05h
 
707
 
 
708
    Output:
 
709
     */
 
710
    pVbe->pInt10->num = 0x10;
 
711
    pVbe->pInt10->ax = 0x4f05;
 
712
    pVbe->pInt10->bx = window;
 
713
    pVbe->pInt10->dx = iBank;
 
714
    xf86ExecX86int10(pVbe->pInt10);
 
715
 
 
716
    if (R16(pVbe->pInt10->ax) != 0x4f)
 
717
        return (FALSE);
 
718
 
 
719
    return (TRUE);
 
720
}
 
721
 
 
722
Bool
 
723
VBESetGetLogicalScanlineLength(vbeInfoPtr pVbe, vbeScanwidthCommand command,
 
724
                                int width, int *pixels, int *bytes, int *max)
 
725
{
 
726
    if (command < SCANWID_SET || command > SCANWID_GET_MAX)
 
727
        return (FALSE);
 
728
 
 
729
    /*
 
730
    Input:
 
731
        AX := 4F06h VBE Set/Get Logical Scan Line Length
 
732
        BL := 00h Set Scan Line Length in Pixels
 
733
           := 01h Get Scan Line Length
 
734
           := 02h Set Scan Line Length in Bytes
 
735
           := 03h Get Maximum Scan Line Length
 
736
        CX := If BL=00h Desired Width in Pixels
 
737
              If BL=02h Desired Width in Bytes
 
738
              (Ignored for Get Functions)
 
739
 
 
740
    Output:
 
741
        AX := VBE Return Status
 
742
        BX := Bytes Per Scan Line
 
743
        CX := Actual Pixels Per Scan Line
 
744
              (truncated to nearest complete pixel)
 
745
        DX := Maximum Number of Scan Lines
 
746
     */
 
747
 
 
748
    pVbe->pInt10->num = 0x10;
 
749
    pVbe->pInt10->ax = 0x4f06;
 
750
    pVbe->pInt10->bx = command;
 
751
    if (command == SCANWID_SET || command == SCANWID_SET_BYTES)
 
752
        pVbe->pInt10->cx = width;
 
753
    xf86ExecX86int10(pVbe->pInt10);
 
754
 
 
755
    if (R16(pVbe->pInt10->ax) != 0x4f)
 
756
        return (FALSE);
 
757
 
 
758
    if (command == SCANWID_GET || command == SCANWID_GET_MAX) {
 
759
        if (pixels)
 
760
            *pixels = R16(pVbe->pInt10->cx);
 
761
        if (bytes)
 
762
            *bytes = R16(pVbe->pInt10->bx);
 
763
        if (max)
 
764
            *max = R16(pVbe->pInt10->dx);
 
765
    }
 
766
 
 
767
    return (TRUE);
 
768
}
 
769
 
 
770
Bool
 
771
VBESetDisplayStart(vbeInfoPtr pVbe, int x, int y, Bool wait_retrace)
 
772
{
 
773
    pVbe->pInt10->num = 0x10;
 
774
    pVbe->pInt10->ax = 0x4f07;
 
775
    pVbe->pInt10->bx = wait_retrace ? 0x80 : 0x00;
 
776
    pVbe->pInt10->cx = x;
 
777
    pVbe->pInt10->dx = y;
 
778
    xf86ExecX86int10(pVbe->pInt10);
 
779
 
 
780
    if (R16(pVbe->pInt10->ax) != 0x4f)
 
781
        return (FALSE);
 
782
 
 
783
    return (TRUE);
 
784
}
 
785
 
 
786
Bool
 
787
VBEGetDisplayStart(vbeInfoPtr pVbe, int *x, int *y)
 
788
{
 
789
    pVbe->pInt10->num = 0x10;
 
790
    pVbe->pInt10->ax = 0x4f07;
 
791
    pVbe->pInt10->bx = 0x01;
 
792
    xf86ExecX86int10(pVbe->pInt10);
 
793
 
 
794
    if (R16(pVbe->pInt10->ax) != 0x4f)
 
795
        return (FALSE);
 
796
 
 
797
    *x = pVbe->pInt10->cx;
 
798
    *y = pVbe->pInt10->dx;
 
799
 
 
800
    return (TRUE);
 
801
}
 
802
 
 
803
int
 
804
VBESetGetDACPaletteFormat(vbeInfoPtr pVbe, int bits)
 
805
{
 
806
    /*
 
807
    Input:
 
808
        AX := 4F08h VBE Set/Get Palette Format
 
809
        BL := 00h Set DAC Palette Format
 
810
           := 01h Get DAC Palette Format
 
811
        BH := Desired bits of color per primary
 
812
              (Set DAC Palette Format only)
 
813
 
 
814
    Output:
 
815
        AX := VBE Return Status
 
816
        BH := Current number of bits of color per primary
 
817
     */
 
818
 
 
819
    pVbe->pInt10->num = 0x10;
 
820
    pVbe->pInt10->ax = 0x4f08;
 
821
    if (!bits)
 
822
        pVbe->pInt10->bx = 0x01;
 
823
    else 
 
824
        pVbe->pInt10->bx = (bits & 0x00ff) << 8;
 
825
    xf86ExecX86int10(pVbe->pInt10);
 
826
 
 
827
    if (R16(pVbe->pInt10->ax) != 0x4f)
 
828
        return (0);
 
829
 
 
830
    return (bits != 0 ? bits : (pVbe->pInt10->bx >> 8) & 0x00ff);
 
831
}
 
832
 
 
833
CARD32 *
 
834
VBESetGetPaletteData(vbeInfoPtr pVbe, Bool set, int first, int num,
 
835
                      CARD32 *data, Bool secondary, Bool wait_retrace)
 
836
{
 
837
    /*
 
838
    Input:
 
839
    (16-bit)
 
840
        AX    := 4F09h VBE Load/Unload Palette Data
 
841
        BL    := 00h Set Palette Data
 
842
              := 01h Get Palette Data
 
843
              := 02h Set Secondary Palette Data
 
844
              := 03h Get Secondary Palette Data
 
845
              := 80h Set Palette Data during Vertical Retrace
 
846
        CX    := Number of palette registers to update (to a maximum of 256)
 
847
        DX    := First of the palette registers to update (start)
 
848
        ES:DI := Table of palette values (see below for format)
 
849
 
 
850
    Output:
 
851
        AX    := VBE Return Status
 
852
 
 
853
 
 
854
    Input:
 
855
    (32-bit)
 
856
        BL     := 00h Set Palette Data
 
857
               := 80h Set Palette Data during Vertical Retrace
 
858
        CX     := Number of palette registers to update (to a maximum of 256)
 
859
        DX     := First of the palette registers to update (start)
 
860
        ES:EDI := Table of palette values (see below for format)
 
861
        DS     := Selector for memory mapped registers
 
862
     */
 
863
 
 
864
    pVbe->pInt10->num = 0x10;
 
865
    pVbe->pInt10->ax = 0x4f09;
 
866
    if (!secondary)
 
867
        pVbe->pInt10->bx = set && wait_retrace ? 0x80 : set ? 0 : 1;
 
868
    else
 
869
        pVbe->pInt10->bx = set ? 2 : 3;
 
870
    pVbe->pInt10->cx = num;
 
871
    pVbe->pInt10->dx = first;
 
872
    pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
 
873
    pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
 
874
    if (set)
 
875
        memcpy(pVbe->memory, data, num * sizeof(CARD32));
 
876
    xf86ExecX86int10(pVbe->pInt10);
 
877
 
 
878
    if (R16(pVbe->pInt10->ax) != 0x4f)
 
879
        return (NULL);
 
880
 
 
881
    if (set)
 
882
        return (data);
 
883
 
 
884
    data = xalloc(num * sizeof(CARD32));
 
885
    memcpy(data, pVbe->memory, num * sizeof(CARD32));
 
886
 
 
887
    return (data);
 
888
}
 
889
 
 
890
VBEpmi *
 
891
VBEGetVBEpmi(vbeInfoPtr pVbe)
 
892
{
 
893
    VBEpmi *pmi;
 
894
 
 
895
    /*
 
896
    Input:
 
897
        AH    := 4Fh    Super VGA support
 
898
        AL    := 0Ah    Protected Mode Interface
 
899
        BL    := 00h    Return Protected Mode Table
 
900
 
 
901
    Output:
 
902
        AX    := Status
 
903
        ES    := Real Mode Segment of Table
 
904
        DI    := Offset of Table
 
905
        CX    := Lenght of Table including protected mode code in bytes (for copying purposes)
 
906
        (All other registers are preserved)
 
907
     */
 
908
 
 
909
    pVbe->pInt10->num = 0x10;
 
910
    pVbe->pInt10->ax = 0x4f0a;
 
911
    pVbe->pInt10->bx = 0;
 
912
    pVbe->pInt10->di = 0;
 
913
    xf86ExecX86int10(pVbe->pInt10);
 
914
 
 
915
    if (R16(pVbe->pInt10->ax) != 0x4f)
 
916
        return (NULL);
 
917
 
 
918
    pmi = xalloc(sizeof(VBEpmi));
 
919
    pmi->seg_tbl = R16(pVbe->pInt10->es);
 
920
    pmi->tbl_off = R16(pVbe->pInt10->di);
 
921
    pmi->tbl_len = R16(pVbe->pInt10->cx);
 
922
 
 
923
    return (pmi);
 
924
}
 
925
 
 
926
#if 0
 
927
vbeModeInfoPtr
 
928
VBEBuildVbeModeList(vbeInfoPtr pVbe, VbeInfoBlock *vbe)
 
929
{
 
930
    vbeModeInfoPtr ModeList = NULL;
 
931
 
 
932
    int i = 0;
 
933
    while (vbe->VideoModePtr[i] != 0xffff) {
 
934
        vbeModeInfoPtr m;
 
935
        VbeModeInfoBlock *mode;
 
936
        int id = vbe->VideoModePtr[i++];
 
937
        int bpp;
 
938
 
 
939
        if ((mode = VBEGetModeInfo(pVbe, id)) == NULL)
 
940
            continue;
 
941
 
 
942
        bpp = mode->BitsPerPixel;
 
943
 
 
944
        m = xnfcalloc(sizeof(vbeModeInfoRec),1);
 
945
        m->width = mode->XResolution;
 
946
        m->height = mode->YResolution;
 
947
        m->bpp = bpp;
 
948
        m->n = id;
 
949
        m->next = ModeList;
 
950
 
 
951
        xf86DrvMsgVerb(pVbe->pInt10->scrnIndex, X_PROBED, 3,
 
952
                       "BIOS reported VESA mode 0x%x: x:%i y:%i bpp:%i\n",
 
953
                       m->n, m->width, m->height, m->bpp);
 
954
 
 
955
        ModeList = m;
 
956
 
 
957
        VBEFreeModeInfo(mode);
 
958
    }
 
959
    return ModeList;
 
960
}
 
961
 
 
962
unsigned short 
 
963
VBECalcVbeModeIndex(vbeModeInfoPtr m, DisplayModePtr mode, int bpp)
 
964
{
 
965
    while (m) {
 
966
        if (bpp == m->bpp 
 
967
            && mode->HDisplay == m->width 
 
968
            && mode->VDisplay == m->height)
 
969
            return m->n;
 
970
        m = m->next;
 
971
    }
 
972
    return 0;
 
973
}
 
974
#endif
 
975
 
 
976
void
 
977
VBEVesaSaveRestore(vbeInfoPtr pVbe, vbeSaveRestorePtr vbe_sr,
 
978
                  vbeSaveRestoreFunction function)
 
979
{
 
980
    Bool SaveSucc = FALSE;
 
981
 
 
982
    if (VBE_VERSION_MAJOR(pVbe->version) > 1
 
983
        && (function == MODE_SAVE || vbe_sr->pstate)) {
 
984
        if (function == MODE_RESTORE)
 
985
            memcpy(vbe_sr->state, vbe_sr->pstate, vbe_sr->stateSize);
 
986
        ErrorF("VBESaveRestore\n");
 
987
        if ((VBESaveRestore(pVbe,function,
 
988
                            (pointer)&vbe_sr->state,
 
989
                            &vbe_sr->stateSize,&vbe_sr->statePage))) {
 
990
            if (function == MODE_SAVE) {
 
991
                SaveSucc = TRUE;
 
992
                vbe_sr->stateMode = -1; /* invalidate */
 
993
                /* don't rely on the memory not being touched */
 
994
                if (vbe_sr->pstate == NULL)
 
995
                    vbe_sr->pstate = xalloc(vbe_sr->stateSize);
 
996
                memcpy(vbe_sr->pstate, vbe_sr->state, vbe_sr->stateSize);
 
997
            }
 
998
            ErrorF("VBESaveRestore done with success\n");
 
999
            return;
 
1000
        }
 
1001
        ErrorF("VBESaveRestore done\n");
 
1002
    } 
 
1003
    
 
1004
    if (function == MODE_SAVE && !SaveSucc)
 
1005
            (void)VBEGetVBEMode(pVbe, &vbe_sr->stateMode);
 
1006
        
 
1007
    if (function == MODE_RESTORE && vbe_sr->stateMode != -1)
 
1008
            VBESetVBEMode(pVbe, vbe_sr->stateMode, NULL);
 
1009
 
 
1010
}
 
1011
 
 
1012
int
 
1013
VBEGetPixelClock(vbeInfoPtr pVbe, int mode, int clock)
 
1014
{
 
1015
    /*
 
1016
    Input:
 
1017
        AX := 4F0Bh VBE Get Pixel Clock
 
1018
        BL := 01h Get Pixel Clock
 
1019
        ECX := pixel clock in units of Hz
 
1020
        DX := mode number
 
1021
     
 
1022
    Output:
 
1023
        AX := VBE Return Status
 
1024
        ECX := Closest pixel clock
 
1025
     */
 
1026
 
 
1027
    pVbe->pInt10->num = 0x10;
 
1028
    pVbe->pInt10->ax = 0x4f0b;
 
1029
    pVbe->pInt10->bx = 0x01;
 
1030
    pVbe->pInt10->cx = clock;
 
1031
    pVbe->pInt10->dx = mode;
 
1032
    xf86ExecX86int10(pVbe->pInt10);
 
1033
 
 
1034
    if (R16(pVbe->pInt10->ax) != 0x4f)
 
1035
        return (0);
 
1036
 
 
1037
    return (pVbe->pInt10->cx);
 
1038
}
 
1039
 
 
1040
Bool
 
1041
VBEDPMSSet(vbeInfoPtr pVbe, int mode)
 
1042
{
 
1043
    /*
 
1044
    Input:
 
1045
        AX := 4F10h DPMS
 
1046
        BL := 01h Set Display Power State
 
1047
        BH := requested power state
 
1048
     
 
1049
    Output:
 
1050
        AX := VBE Return Status
 
1051
     */
 
1052
 
 
1053
    pVbe->pInt10->num = 0x10;
 
1054
    pVbe->pInt10->ax = 0x4f10;
 
1055
    pVbe->pInt10->bx = 0x01;
 
1056
    switch (mode) {
 
1057
    case DPMSModeOn:
 
1058
        break;
 
1059
    case DPMSModeStandby:
 
1060
        pVbe->pInt10->bx |= 0x100;
 
1061
        break;
 
1062
    case DPMSModeSuspend:
 
1063
        pVbe->pInt10->bx |= 0x200;
 
1064
        break;
 
1065
    case DPMSModeOff:
 
1066
        pVbe->pInt10->bx |= 0x400;
 
1067
        break;
 
1068
    }
 
1069
    xf86ExecX86int10(pVbe->pInt10);
 
1070
    return (R16(pVbe->pInt10->ax) == 0x4f);
 
1071
}
 
1072