~smartboyhw/wubi/bug-1080090-new

« back to all changes in this revision

Viewing changes to src/grub4dos/stage2/.svn/text-base/graphics.c.svn-base

  • Committer: Howard Chan
  • Date: 2012-11-20 10:16:05 UTC
  • Revision ID: smartboyhw@gmail.com-20121120101605-qfmjfsdynpzg9an9
Added images

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* graphics.c - graphics mode support for GRUB */
2
 
/* Implemented as a terminal type by Jeremy Katz <katzj@redhat.com> based
3
 
 * on a patch by Paulo Cďż˝sar Pereira de Andrade <pcpa@conectiva.com.br>
4
 
 */
5
 
/*
6
 
 *  GRUB  --  GRand Unified Bootloader
7
 
 *  Copyright (C) 2001,2002  Red Hat, Inc.
8
 
 *  Portions copyright (C) 2000  Conectiva, Inc.
9
 
 *
10
 
 *  This program is free software; you can redistribute it and/or modify
11
 
 *  it under the terms of the GNU General Public License as published by
12
 
 *  the Free Software Foundation; either version 2 of the License, or
13
 
 *  (at your option) any later version.
14
 
 *
15
 
 *  This program is distributed in the hope that it will be useful,
16
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 
 *  GNU General Public License for more details.
19
 
 *
20
 
 *  You should have received a copy of the GNU General Public License
21
 
 *  along with this program; if not, write to the Free Software
22
 
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
 
 */
24
 
 
25
 
 
26
 
 
27
 
#ifdef SUPPORT_GRAPHICS
28
 
 
29
 
#include <term.h>
30
 
#include <shared.h>
31
 
#include <graphics.h>
32
 
 
33
 
static int saved_videomode = 0;
34
 
static unsigned char *font8x16 = 0;
35
 
 
36
 
int outline = 0;
37
 
int disable_space_highlight = 0;
38
 
int graphics_inited = 0;
39
 
char splashimage[64];
40
 
 
41
 
#define VSHADOW VSHADOW1
42
 
/* 8x16 dot array, total chars = 80*30. plano size = 80*30*16 = 38400 bytes */
43
 
static unsigned char *VSHADOW1 = (unsigned char *)0x3A0000;     //unsigned char VSHADOW1[38400];
44
 
static unsigned char *VSHADOW2 = (unsigned char *)0x3A9600;     //unsigned char VSHADOW2[38400];
45
 
static unsigned char *VSHADOW4 = (unsigned char *)0x3B2C00;     //unsigned char VSHADOW4[38400];
46
 
static unsigned char *VSHADOW8 = (unsigned char *)0x3BC200;     //unsigned char VSHADOW8[38400];
47
 
/* text buffer has to be kept around so that we can write things as we
48
 
 * scroll and the like */
49
 
//static unsigned short text[80 * 30];
50
 
static unsigned long *text = (unsigned long *)0x3C5800; // length in bytes = 80*30*4
51
 
 
52
 
/* constants to define the viewable area */
53
 
const int x0 = 0;
54
 
const int x1 = 80;
55
 
const int y0 = 0;
56
 
const int y1 = 30;
57
 
 
58
 
/* why do these have to be kept here? */
59
 
int foreground = (63 << 16) | (63 << 8) | (63), background = 0, border = 0;
60
 
 
61
 
/* current position */
62
 
static int fontx = 0;
63
 
static int fonty = 0;
64
 
 
65
 
/* global state so that we don't try to recursively scroll or cursor */
66
 
static int no_scroll = 0;
67
 
 
68
 
/* color state */
69
 
static int graphics_standard_color = A_NORMAL;
70
 
static int graphics_normal_color = A_NORMAL;
71
 
static int graphics_highlight_color = A_REVERSE;
72
 
static int graphics_current_color = A_NORMAL;
73
 
static color_state graphics_color_state = COLOR_STATE_STANDARD;
74
 
 
75
 
 
76
 
/* graphics local functions */
77
 
static void graphics_setxy (int col, int row);
78
 
static void graphics_scroll (void);
79
 
static int read_image (char *s);
80
 
 
81
 
/* FIXME: where do these really belong? */
82
 
static inline void outb(unsigned short port, unsigned char val)
83
 
{
84
 
    __asm __volatile ("outb %0,%1"::"a" (val), "d" (port));
85
 
}
86
 
 
87
 
static void MapMask(int value) {
88
 
    outb(0x3c4, 2);
89
 
    outb(0x3c5, value);
90
 
}
91
 
 
92
 
/* bit mask register */
93
 
static void BitMask(int value) {
94
 
    outb(0x3ce, 8);
95
 
    outb(0x3cf, value);
96
 
}
97
 
 
98
 
 
99
 
 
100
 
///* Set the splash image */
101
 
//void graphics_set_splash(char *splashfile) {
102
 
//    grub_strcpy(splashimage, splashfile);
103
 
//}
104
 
 
105
 
///* Get the current splash image */
106
 
//char *graphics_get_splash(void) {
107
 
//    return splashimage;
108
 
//}
109
 
 
110
 
/* Initialize a vga16 graphics display with the palette based off of
111
 
 * the image in splashimage.  If the image doesn't exist, leave graphics
112
 
 * mode.  */
113
 
int
114
 
graphics_init (void)
115
 
{
116
 
    /* graphics mode will corrupt the extended memory. so we should
117
 
     * invalidate the kernel_type. */
118
 
    kernel_type = KERNEL_TYPE_NONE;
119
 
 
120
 
    if (! graphics_inited)
121
 
    {
122
 
        saved_videomode = set_videomode (0x12);
123
 
    }
124
 
 
125
 
    if (! read_image (splashimage))
126
 
    {
127
 
        set_videomode (saved_videomode);
128
 
        grub_printf("failed to read image\n");
129
 
        return 0;
130
 
    }
131
 
 
132
 
    font8x16 = (unsigned char *) graphics_get_font (); /* code in asm.S */
133
 
 
134
 
    graphics_inited = 1;
135
 
 
136
 
    /* make sure that the highlight color is set correctly */
137
 
    graphics_highlight_color = ((graphics_normal_color >> 4) | 
138
 
                                ((graphics_normal_color & 0xf) << 4));
139
 
 
140
 
    return 1;
141
 
}
142
 
 
143
 
/* Leave graphics mode */
144
 
void
145
 
graphics_end (void)
146
 
{
147
 
    if (graphics_inited)
148
 
    {
149
 
        set_videomode (saved_videomode);
150
 
        graphics_inited = 0;
151
 
    }
152
 
}
153
 
 
154
 
/* Print ch on the screen.  Handle any needed scrolling or the like */
155
 
void
156
 
graphics_putchar (int ch)
157
 
{
158
 
    ch &= 0xff;
159
 
 
160
 
    graphics_cursor(0);
161
 
 
162
 
    if (ch == '\n') {
163
 
        if (fonty + 1 < y1)
164
 
            graphics_setxy(fontx, fonty + 1);
165
 
        else
166
 
            graphics_scroll();
167
 
        graphics_cursor(1);
168
 
        return;
169
 
    } else if (ch == '\r') {
170
 
        graphics_setxy(x0, fonty);
171
 
        graphics_cursor(1);
172
 
        return;
173
 
    }
174
 
 
175
 
    graphics_cursor(0);
176
 
 
177
 
    text[fonty * 80 + fontx] = ch;
178
 
    text[fonty * 80 + fontx] &= 0x00ff;
179
 
    if (graphics_current_color & 0xf0)
180
 
        text[fonty * 80 + fontx] |= 0x10000;//0x100;
181
 
 
182
 
    graphics_cursor(0);
183
 
 
184
 
    if ((fontx + 1) >= x1) {
185
 
        graphics_setxy(x0, fonty);
186
 
        if (fonty + 1 < y1)
187
 
            graphics_setxy(x0, fonty + 1);
188
 
        else
189
 
            graphics_scroll();
190
 
    } else {
191
 
        graphics_setxy(fontx + 1, fonty);
192
 
    }
193
 
 
194
 
    graphics_cursor(1);
195
 
}
196
 
 
197
 
/* get the current location of the cursor */
198
 
int
199
 
graphics_getxy(void)
200
 
{
201
 
    return (fontx << 8) | fonty;
202
 
}
203
 
 
204
 
void
205
 
graphics_gotoxy (int x, int y)
206
 
{
207
 
    graphics_cursor(0);
208
 
 
209
 
    graphics_setxy(x, y);
210
 
 
211
 
    graphics_cursor(1);
212
 
}
213
 
 
214
 
void
215
 
graphics_cls (void)
216
 
{
217
 
    int i;
218
 
    unsigned char *mem, *s1, *s2, *s4, *s8;
219
 
 
220
 
    graphics_cursor(0);
221
 
    graphics_gotoxy(x0, y0);
222
 
 
223
 
    mem = (unsigned char*)VIDEOMEM;
224
 
    s1 = (unsigned char*)VSHADOW1;
225
 
    s2 = (unsigned char*)VSHADOW2;
226
 
    s4 = (unsigned char*)VSHADOW4;
227
 
    s8 = (unsigned char*)VSHADOW8;
228
 
 
229
 
    for (i = 0; i < 80 * 30; i++)
230
 
        text[i] = ' ';
231
 
    graphics_cursor(1);
232
 
 
233
 
    BitMask(0xff);
234
 
 
235
 
    /* plano 1 */
236
 
    MapMask(1);
237
 
    grub_memcpy(mem, s1, 38400);
238
 
 
239
 
    /* plano 2 */
240
 
    MapMask(2);
241
 
    grub_memcpy(mem, s2, 38400);
242
 
 
243
 
    /* plano 3 */
244
 
    MapMask(4);
245
 
    grub_memcpy(mem, s4, 38400);
246
 
 
247
 
    /* plano 4 */
248
 
    MapMask(8);
249
 
    grub_memcpy(mem, s8, 38400);
250
 
 
251
 
    MapMask(15);
252
 
 
253
 
}
254
 
 
255
 
void
256
 
graphics_setcolorstate (color_state state)
257
 
{
258
 
    switch (state)
259
 
    {
260
 
        case COLOR_STATE_STANDARD:
261
 
                graphics_current_color = graphics_standard_color;
262
 
                break;
263
 
        case COLOR_STATE_NORMAL:
264
 
                graphics_current_color = graphics_normal_color;
265
 
                break;
266
 
        case COLOR_STATE_HIGHLIGHT:
267
 
                graphics_current_color = graphics_highlight_color;
268
 
                break;
269
 
        default:
270
 
                graphics_current_color = graphics_standard_color;
271
 
                break;
272
 
    }
273
 
 
274
 
    graphics_color_state = state;
275
 
}
276
 
 
277
 
void
278
 
graphics_setcolor (int normal_color, int highlight_color)
279
 
{
280
 
    graphics_normal_color = normal_color;
281
 
    graphics_highlight_color = highlight_color;
282
 
 
283
 
    graphics_setcolorstate (graphics_color_state);
284
 
}
285
 
 
286
 
int
287
 
graphics_setcursor (int on)
288
 
{
289
 
    /* FIXME: we don't have a cursor in graphics */
290
 
    return 0;
291
 
}
292
 
 
293
 
/* Read in the splashscreen image and set the palette up appropriately.
294
 
 * Format of splashscreen is an xpm (can be gzipped) with 16 colors and
295
 
 * 640x480. */
296
 
static int
297
 
read_image (char *s)
298
 
{
299
 
    char buf[32], pal[16];
300
 
    unsigned char c, base, mask;
301
 
    unsigned i, len, idx, colors, x, y, width, height;
302
 
 
303
 
    unsigned char *s1 = (unsigned char*)VSHADOW1;
304
 
    unsigned char *s2 = (unsigned char*)VSHADOW2;
305
 
    unsigned char *s4 = (unsigned char*)VSHADOW4;
306
 
    unsigned char *s8 = (unsigned char*)VSHADOW8;
307
 
 
308
 
    if (! grub_open(s))
309
 
    {
310
 
        errnum = 0;
311
 
        //graphics_set_palette(1, 0, 0, 0);
312
 
        
313
 
        for (i = 0; i < 38400 / 4; i++)
314
 
                ((long *)s1)[i] = ((long *)s2)[i] = ((long *)s4)[i] = ((long *)s8)[i] = 0;
315
 
 
316
 
        //for (y = 0, len = 0; y < 480; y++, len += 80) {
317
 
        //    for (x = 0; x < 640; x++) {
318
 
        //      s1[len + (x >> 3)] |= 0x80 >> (x & 7);
319
 
        //    }
320
 
        //}
321
 
 
322
 
        goto set_palette;       //return 0;
323
 
    }
324
 
 
325
 
    /* read header */
326
 
    if (! grub_read((char*)&buf, 10) || grub_memcmp(buf, "/* XPM */\n", 10)) {
327
 
        grub_close();
328
 
        return 0;
329
 
    }
330
 
    
331
 
    /* parse info */
332
 
    while (grub_read((char *)&c, 1)) {
333
 
        if (c == '"')
334
 
            break;
335
 
    }
336
 
 
337
 
    while (grub_read((char *)&c, 1) && (c == ' ' || c == '\t'))
338
 
        ;
339
 
 
340
 
    i = 0;
341
 
    width = c - '0';
342
 
    while (grub_read((char *)&c, 1)) {
343
 
        if (c >= '0' && c <= '9')
344
 
            width = width * 10 + c - '0';
345
 
        else
346
 
            break;
347
 
    }
348
 
    while (grub_read((char *)&c, 1) && (c == ' ' || c == '\t'))
349
 
        ;
350
 
 
351
 
    height = c - '0';
352
 
    while (grub_read((char *)&c, 1)) {
353
 
        if (c >= '0' && c <= '9')
354
 
            height = height * 10 + c - '0';
355
 
        else
356
 
            break;
357
 
    }
358
 
    while (grub_read((char *)&c, 1) && (c == ' ' || c == '\t'))
359
 
        ;
360
 
 
361
 
    colors = c - '0';
362
 
    while (grub_read((char *)&c, 1)) {
363
 
        if (c >= '0' && c <= '9')
364
 
            colors = colors * 10 + c - '0';
365
 
        else
366
 
            break;
367
 
    }
368
 
 
369
 
    base = 0;
370
 
    while (grub_read((char *)&c, 1) && c != '"')
371
 
        ;
372
 
 
373
 
    /* palette */
374
 
    for (i = 0, idx = 1; i < colors; i++) {
375
 
        len = 0;
376
 
 
377
 
        while (grub_read((char *)&c, 1) && c != '"')
378
 
            ;
379
 
        grub_read((char *)&c, 1);       /* char */
380
 
        base = c;
381
 
        grub_read(buf, 4);      /* \t c # */
382
 
 
383
 
        while (grub_read((char *)&c, 1) && c != '"') {
384
 
            if (len < sizeof(buf))
385
 
                buf[len++] = c;
386
 
        }
387
 
 
388
 
        if (len == 6 && idx < 15) {
389
 
            int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2;
390
 
            int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2;
391
 
            int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2;
392
 
 
393
 
            pal[idx] = base;
394
 
            graphics_set_palette(idx, r, g, b);
395
 
            ++idx;
396
 
        }
397
 
    }
398
 
 
399
 
    x = y = len = 0;
400
 
 
401
 
    for (i = 0; i < 38400 / 4; i++)
402
 
        ((long *)s1)[i] = ((long *)s2)[i] = ((long *)s4)[i] = ((long *)s8)[i] = 0;
403
 
 
404
 
    /* parse xpm data */
405
 
    while (y < height) {
406
 
        while (1) {
407
 
            if (!grub_read((char *)&c, 1)) {
408
 
                grub_close();
409
 
                return 0;
410
 
            }
411
 
            if (c == '"')
412
 
                break;
413
 
        }
414
 
 
415
 
        while (grub_read((char *)&c, 1) && c != '"') {
416
 
            for (i = 1; i < 15; i++)
417
 
                if (pal[i] == c) {
418
 
                    c = i;
419
 
                    break;
420
 
                }
421
 
 
422
 
            mask = 0x80 >> (x & 7);
423
 
            if (c & 1)
424
 
                s1[len + (x >> 3)] |= mask;
425
 
            if (c & 2)
426
 
                s2[len + (x >> 3)] |= mask;
427
 
            if (c & 4)
428
 
                s4[len + (x >> 3)] |= mask;
429
 
            if (c & 8)
430
 
                s8[len + (x >> 3)] |= mask;
431
 
 
432
 
            if (++x >= 640) {
433
 
                x = 0;
434
 
 
435
 
                if (y < 480)
436
 
                    len += 80;
437
 
                ++y;
438
 
            }
439
 
        }
440
 
    }
441
 
 
442
 
    grub_close();
443
 
 
444
 
set_palette:
445
 
 
446
 
    graphics_set_palette(0, (background >> 16), (background >> 8) & 63, 
447
 
                background & 63);
448
 
    graphics_set_palette(15, (foreground >> 16), (foreground >> 8) & 63, 
449
 
                foreground & 63);
450
 
    graphics_set_palette(0x11, (border >> 16), (border >> 8) & 63, 
451
 
                         border & 63);
452
 
 
453
 
    return 1;
454
 
}
455
 
 
456
 
 
457
 
/* Convert a character which is a hex digit to the appropriate integer */
458
 
int
459
 
hex (int v)
460
 
{
461
 
    if (v >= 'A' && v <= 'F')
462
 
        return (v - 'A' + 10);
463
 
    if (v >= 'a' && v <= 'f')
464
 
        return (v - 'a' + 10);
465
 
    return (v - '0');
466
 
}
467
 
 
468
 
 
469
 
/* move the graphics cursor location to col, row */
470
 
static void
471
 
graphics_setxy (int col, int row)
472
 
{
473
 
    if (col >= x0 && col < x1)
474
 
    {
475
 
        fontx = col;
476
 
        cursorX = col << 3;
477
 
    }
478
 
 
479
 
    if (row >= y0 && row < y1)
480
 
    {
481
 
        fonty = row;
482
 
        cursorY = row << 4;
483
 
    }
484
 
}
485
 
 
486
 
/* scroll the screen */
487
 
static void
488
 
graphics_scroll (void)
489
 
{
490
 
    int i, j;
491
 
 
492
 
    /* we don't want to scroll recursively... that would be bad */
493
 
    if (no_scroll)
494
 
        return;
495
 
    no_scroll = 1;
496
 
 
497
 
    /* move everything up a line */
498
 
    for (j = y0 + 1; j < y1; j++)
499
 
    {
500
 
        graphics_gotoxy (x0, j - 1);
501
 
 
502
 
        for (i = x0; i < x1; i++)
503
 
        {
504
 
            graphics_putchar (text[j * 80 + i]);
505
 
        }
506
 
    }
507
 
 
508
 
    /* last line should be blank */
509
 
    graphics_gotoxy (x0, y1 - 1);
510
 
 
511
 
    for (i = x0; i < x1; i++)
512
 
        graphics_putchar (' ');
513
 
 
514
 
    graphics_setxy (x0, y1 - 1);
515
 
 
516
 
    no_scroll = 0;
517
 
}
518
 
 
519
 
 
520
 
static unsigned char chr[16 << 2];
521
 
static unsigned char mask[16];
522
 
 
523
 
static void
524
 
graphics_cursor (int set)
525
 
{
526
 
    unsigned char *pat, *mem, *ptr;
527
 
    int i, ch, offset;
528
 
    int invert = 0;
529
 
 
530
 
    if (set && no_scroll)
531
 
        return;
532
 
 
533
 
    offset = cursorY * 80 + fontx;
534
 
    ch = text[fonty * 80 + fontx] & 0xff;
535
 
    if (ch != ' ' || ! disable_space_highlight)
536
 
        invert = (text[fonty * 80 + fontx] & /*0xff00*/ 0xffff0000) != 0;
537
 
    pat = font8x16 + (ch << 4);
538
 
 
539
 
    mem = (unsigned char*)VIDEOMEM + offset;
540
 
 
541
 
    if (set)
542
 
    {
543
 
        MapMask(15);
544
 
        ptr = mem;
545
 
        for (i = 0; i < 16; i++, ptr += 80)
546
 
        {
547
 
            cursorBuf[i] = pat[i];
548
 
            *ptr = ~pat[i];
549
 
        }
550
 
        return;
551
 
    }
552
 
 
553
 
    if (outline)
554
 
      for (i = 0; i < 16; i++)
555
 
      {
556
 
        mask[i] = pat[i];
557
 
        if (i < 15)
558
 
                mask[i] |= pat[i+1];
559
 
        if (i > 0)
560
 
                mask[i] |= pat[i-1];
561
 
        mask[i] |= (mask[i] << 1) | (mask[i] >> 1);
562
 
        mask[i] = ~(mask[i]);
563
 
      }
564
 
 
565
 
    for (i = 0; i < 16; i++, offset += 80)
566
 
    {
567
 
        unsigned char m, p, c1, c2, c4, c8;
568
 
 
569
 
        p = pat[i];
570
 
 
571
 
        if (invert)
572
 
        {
573
 
                p = ~p;
574
 
                chr[i     ] = p;
575
 
                chr[16 + i] = p;
576
 
                chr[32 + i] = p;
577
 
                chr[48 + i] = p;
578
 
                continue;
579
 
        }
580
 
 
581
 
        c1 = ((unsigned char*)VSHADOW1)[offset];
582
 
        c2 = ((unsigned char*)VSHADOW2)[offset];
583
 
        c4 = ((unsigned char*)VSHADOW4)[offset];
584
 
        c8 = ((unsigned char*)VSHADOW8)[offset];
585
 
 
586
 
        if (outline)
587
 
        {
588
 
                m = mask[i];
589
 
 
590
 
                c1 &= m;
591
 
                c2 &= m;
592
 
                c4 &= m;
593
 
                c8 &= m;
594
 
        }
595
 
        
596
 
        c1 |= p;
597
 
        c2 |= p;
598
 
        c4 |= p;
599
 
        c8 |= p;
600
 
 
601
 
#if 0   
602
 
        if (invert)
603
 
        {
604
 
                c1 = ~c1;
605
 
                c2 = ~c2;
606
 
                c4 = ~c4;
607
 
                c8 = ~c8;
608
 
        }
609
 
#endif
610
 
 
611
 
        chr[i     ] = c1;
612
 
        chr[16 + i] = c2;
613
 
        chr[32 + i] = c4;
614
 
        chr[48 + i] = c8;
615
 
    }
616
 
 
617
 
    offset = 0;
618
 
    for (i = 1; i < 16; i <<= 1, offset += 16)
619
 
    {
620
 
        int j;
621
 
 
622
 
        MapMask(i);
623
 
        ptr = mem;
624
 
        for (j = 0; j < 16; j++, ptr += 80)
625
 
            *ptr = chr[j + offset];
626
 
    }
627
 
 
628
 
    MapMask(15);
629
 
}
630
 
 
631
 
#endif /* SUPPORT_GRAPHICS */