aboutsummaryrefslogtreecommitdiffstats
path: root/demos/modules/gwin/slider/gfxconf.h
blob: 9d55d29f6f4d0e6690e07b6f5498b94bff7d8850 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/*
 * Copyright (c) 2012, 2013, Joel Bodenmann aka Tectu <joel@unormal.org>
 * Copyright (c) 2012, 2013, Andrew Hannam aka inmarket
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *    * Neither the name of the <organization> nor the
 *      names of its contributors may be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _GFXCONF_H
#define _GFXCONF_H

/* The operating system to use. One of these must be defined - preferably in your Makefile */
//#define GFX_USE_OS_CHIBIOS	FALSE
//#define GFX_USE_OS_WIN32		FALSE
//#define GFX_USE_OS_LINUX		FALSE
//#define GFX_USE_OS_OSX		FALSE

/* GFX sub-systems to turn on */
#define GFX_USE_GDISP			TRUE
#define GFX_USE_GWIN			TRUE
#define GFX_USE_GINPUT			TRUE
#define GFX_USE_GEVENT			TRUE
#define GFX_USE_GTIMER			TRUE
#define GFX_USE_GQUEUE			TRUE

/* Features for the GDISP sub-system. */
#define GDISP_NEED_VALIDATION	TRUE
#define GDISP_NEED_CLIP			TRUE
#define GDISP_NEED_CIRCLE		TRUE
#define GDISP_NEED_TEXT			TRUE
#define GDISP_NEED_MULTITHREAD	TRUE

/* GDISP fonts to include */
#define GDISP_INCLUDE_FONT_UI2	TRUE

/* Features for the GWIN subsystem. */
#define GWIN_NEED_WINDOWMANAGER	TRUE
#define GWIN_NEED_WIDGET		TRUE
#define GWIN_NEED_SLIDER		TRUE
#define GWIN_NEED_CONSOLE		TRUE

/* Features for the GINPUT subsystem. */
#define GINPUT_NEED_MOUSE		TRUE

/* Features for the GQUEUE subsystem. */
#define GQUEUE_NEED_ASYNC		TRUE

#endif /* _GFXCONF_H */
#666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/******************************************************************************
 * vesa.c
 *
 * VESA linear frame buffer handling.
 */

#include <xen/config.h>
#include <xen/init.h>
#include <xen/lib.h>
#include <xen/mm.h>
#include <xen/errno.h>
#include <xen/console.h>
#include <xen/vga.h>
#include "font.h"

#define vlfb_info    vga_console_info.u.vesa_lfb
#define text_columns (vlfb_info.width / font->width)
#define text_rows    (vlfb_info.height / font->height)

static void vesa_redraw_puts(const char *s);
static void vesa_scroll_puts(const char *s);

static unsigned char *lfb, *lbuf, *text_buf;
static const struct font_desc *font;
static bool_t vga_compat;
static unsigned int pixel_on;
static unsigned int xpos, ypos;

static unsigned int vram_total;
integer_param("vesa-ram", vram_total);

static unsigned int vram_remap;
integer_param("vesa-map", vram_remap);

static int font_height;
static void __init parse_font_height(const char *s)
{
    if ( simple_strtoul(s, &s, 10) == 8 && (*s++ == 'x') )
        font_height = simple_strtoul(s, &s, 10);
    if ( *s != '\0' )
        font_height = 0;
}
custom_param("font", parse_font_height);

void __init vesa_early_init(void)
{
    unsigned int vram_vmode;

    vga_compat = !(vga_console_info.u.vesa_lfb.gbl_caps & 2);

    if ( (vlfb_info.bits_per_pixel < 8) || (vlfb_info.bits_per_pixel > 32) )
        return;

    if ( font_height == 0 ) /* choose a sensible default */
        font = ((vlfb_info.height <= 600) ? &font_vga_8x8 :
                (vlfb_info.height <= 768) ? &font_vga_8x14 : &font_vga_8x16);
    else if ( font_height <= 8 )
        font = &font_vga_8x8;
    else if ( font_height <= 14 )
        font = &font_vga_8x14;
    else
        font = &font_vga_8x16;

    /*   vram_vmode -- that is the amount of memory needed for the
     *                 used video mode, i.e. the minimum amount of
     *                 memory we need. */
    vram_vmode = vlfb_info.height * vlfb_info.bytes_per_line;

    /*   vram_total -- all video memory we have. Used for mtrr
     *                 entries. */
    vram_total = vram_total ? (vram_total << 20) : (vlfb_info.lfb_size << 16);
    vram_total = max_t(unsigned int, vram_total, vram_vmode);

    /*   vram_remap -- the amount of video memory we are going to
     *                 use for vesafb.  With modern cards it is no
     *                 option to simply use vram_total as that
     *                 wastes plenty of kernel address space. */
    vram_remap = (vram_remap ?
                  (vram_remap << 20) :
                  ((vram_vmode + (1 << L2_PAGETABLE_SHIFT) - 1) &
                   ~((1 << L2_PAGETABLE_SHIFT) - 1)));
    vram_remap = max_t(unsigned int, vram_remap, vram_vmode);
    vram_remap = min_t(unsigned int, vram_remap, vram_total);
}

void __init vesa_init(void)
{
    if ( !font )
        goto fail;

    lbuf = xmalloc_bytes(vlfb_info.bytes_per_line);
    if ( !lbuf )
        goto fail;

    text_buf = xmalloc_bytes(text_columns * text_rows);
    if ( !text_buf )
        goto fail;

    if ( map_pages_to_xen(IOREMAP_VIRT_START,
                          vlfb_info.lfb_base >> PAGE_SHIFT,
                          vram_remap >> PAGE_SHIFT,
                          PAGE_HYPERVISOR_NOCACHE) )
        goto fail;

    lfb = memset((void *)IOREMAP_VIRT_START, 0, vram_remap);
    memset(text_buf, 0, text_columns * text_rows);

    vga_puts = vesa_redraw_puts;

    printk(XENLOG_INFO "vesafb: framebuffer at 0x%x, mapped to 0x%p, "
           "using %uk, total %uk\n",
           vlfb_info.lfb_base, lfb,
           vram_remap >> 10, vram_total >> 10);
    printk(XENLOG_INFO "vesafb: mode is %dx%dx%u, linelength=%d, font %ux%u\n",
           vlfb_info.width, vlfb_info.height,
           vlfb_info.bits_per_pixel, vlfb_info.bytes_per_line,
           font->width, font->height);
    printk(XENLOG_INFO "vesafb: %scolor: size=%d:%d:%d:%d, "
           "shift=%d:%d:%d:%d\n",
           vlfb_info.bits_per_pixel > 8 ? "True" :
           vga_compat ? "Pseudo" : "Static Pseudo",
           vlfb_info.rsvd_size, vlfb_info.red_size,
           vlfb_info.green_size, vlfb_info.blue_size,
           vlfb_info.rsvd_pos, vlfb_info.red_pos,
           vlfb_info.green_pos, vlfb_info.blue_pos);

    if ( vlfb_info.bits_per_pixel > 8 )
    {
        /* Light grey in truecolor. */
        unsigned int grey = 0xaaaaaaaa;
        pixel_on = 
            ((grey >> (32 - vlfb_info.  red_size)) << vlfb_info.  red_pos) |
            ((grey >> (32 - vlfb_info.green_size)) << vlfb_info.green_pos) |
            ((grey >> (32 - vlfb_info. blue_size)) << vlfb_info. blue_pos);
    }
    else
    {
        /* White(ish) in default pseudocolor palette. */
        pixel_on = 7;
    }

    return;

 fail:
    xfree(lbuf);
    xfree(text_buf);
}

void __init vesa_endboot(void)
{
    xpos = 0;
    vga_puts = vesa_scroll_puts;
}

#if defined(CONFIG_X86)

#include <asm/mtrr.h>

static unsigned int vesa_mtrr;
integer_param("vesa-mtrr", vesa_mtrr);

void __init vesa_mtrr_init(void)
{
    static const int mtrr_types[] = {
        0, MTRR_TYPE_UNCACHABLE, MTRR_TYPE_WRBACK,
        MTRR_TYPE_WRCOMB, MTRR_TYPE_WRTHROUGH };
    unsigned int size_total;
    int rc, type;

    if ( !lfb || (vesa_mtrr == 0) || (vesa_mtrr >= ARRAY_SIZE(mtrr_types)) )
        return;

    type = mtrr_types[vesa_mtrr];
    if ( !type )
        return;

    /* Find the largest power-of-two */
    size_total = vram_total;
    while ( size_total & (size_total - 1) )
        size_total &= size_total - 1;

    /* Try and find a power of two to add */
    do {
        rc = mtrr_add(vlfb_info.lfb_base, size_total, type, 1);
        size_total >>= 1;
    } while ( (size_total >= PAGE_SIZE) && (rc == -EINVAL) );
}

static void lfb_flush(void)
{
    if ( vesa_mtrr == 3 )
        __asm__ __volatile__ ("sfence" : : : "memory");
}

#else /* !defined(CONFIG_X86) */

#define lfb_flush() ((void)0)

#endif

/* Render one line of text to given linear framebuffer line. */
static void vesa_show_line(
    const unsigned char *text_line,
    unsigned char *video_line,
    unsigned int nr_chars)
{
    unsigned int i, j, b, bpp, pixel;

    bpp = (vlfb_info.bits_per_pixel + 7) >> 3;

    for ( i = 0; i < font->height; i++ )
    {
        unsigned char *ptr = lbuf;

        for ( j = 0; j < nr_chars; j++ )
        {
            const unsigned char *bits = font->data;
            bits += ((text_line[j] * font->height + i) *
                     ((font->width + 7) >> 3));
            for ( b = font->width; b--; )
            {
                pixel = (*bits & (1u<<b)) ? pixel_on : 0;
                memcpy(ptr, &pixel, bpp);
                ptr += bpp;
            }
        }

        memset(ptr, 0, (vlfb_info.width - nr_chars * font->width) * bpp);
        memcpy(video_line, lbuf, vlfb_info.width * bpp);
        video_line += vlfb_info.bytes_per_line;
    }
}

/* Fast mode which redraws all modified parts of a 2D text buffer. */
static void vesa_redraw_puts(const char *s)
{
    unsigned int i, min_redraw_y = ypos;
    char c;

    /* Paste characters into text buffer. */
    while ( (c = *s++) != '\0' )
    {
        if ( (c == '\n') || (xpos >= text_columns) )
        {
            if ( ++ypos >= text_rows )
            {
                min_redraw_y = 0;
                ypos = text_rows - 1;
                memmove(text_buf, text_buf + text_columns,
                        ypos * text_columns);
                memset(text_buf + ypos * text_columns, 0, xpos);
            }
            xpos = 0;
        }

        if ( c != '\n' )
            text_buf[xpos++ + ypos * text_columns] = c;
    }

    /* Render modified section of text buffer to VESA linear framebuffer. */
    for ( i = min_redraw_y; i <= ypos; i++ )
        vesa_show_line(text_buf + i * text_columns,
                       lfb + i * font->height * vlfb_info.bytes_per_line,
                       text_columns);

    lfb_flush();
}

/* Slower line-based scroll mode which interacts better with dom0. */
static void vesa_scroll_puts(const char *s)
{
    unsigned int i;
    char c;

    while ( (c = *s++) != '\0' )
    {
        if ( (c == '\n') || (xpos >= text_columns) )
        {
            unsigned int bytes = (vlfb_info.width *
                                  ((vlfb_info.bits_per_pixel + 7) >> 3));
            unsigned char *src = lfb + font->height * vlfb_info.bytes_per_line;
            unsigned char *dst = lfb;
            
            /* New line: scroll all previous rows up one line. */
            for ( i = font->height; i < vlfb_info.height; i++ )
            {
                memcpy(dst, src, bytes);
                src += vlfb_info.bytes_per_line;
                dst += vlfb_info.bytes_per_line;
            }

            /* Render new line. */
            vesa_show_line(
                text_buf,
                lfb + (text_rows-1) * font->height * vlfb_info.bytes_per_line,
                xpos);

            xpos = 0;
        }

        if ( c != '\n' )
            text_buf[xpos++] = c;
    }

    lfb_flush();
}