Revision 4d3b6f6e

b/Makefile
99 99
ifdef CONFIG_SDL
100 100
OBJS+=sdl.o x_keymap.o
101 101
endif
102
ifdef CONFIG_CURSES
103
OBJS+=curses.o
104
endif
102 105
OBJS+=vnc.o d3des.o
103 106

  
104 107
ifdef CONFIG_COCOA
......
122 125
vnc.o: vnc.c keymaps.c sdl_keysym.h vnchextile.h d3des.c d3des.h
123 126
	$(CC) $(CFLAGS) $(CPPFLAGS) $(CONFIG_VNC_TLS_CFLAGS) -c -o $@ $<
124 127

  
128
curses.o: curses.c keymaps.c curses_keys.h
129
	$(CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
130

  
125 131
audio/sdlaudio.o: audio/sdlaudio.c
126 132
	$(CC) $(CFLAGS) $(CPPFLAGS) $(SDL_CFLAGS) -c -o $@ $<
127 133

  
b/Makefile.target
647 647
endif
648 648

  
649 649
$(QEMU_PROG): $(OBJS) ../libqemu_common.a libqemu.a
650
	$(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS)
650
	$(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(CURSES_LIBS)
651 651

  
652 652
endif # !CONFIG_USER_ONLY
653 653

  
b/configure
108 108
darwin_user="no"
109 109
build_docs="no"
110 110
uname_release=""
111
curses="yes"
111 112

  
112 113
# OS specific
113 114
targetos=`uname -s`
......
323 324
  ;;
324 325
  --disable-werror) werror="no"
325 326
  ;;
327
  --disable-curses) curses="no"
328
  ;;
326 329
  *) echo "ERROR: unknown option $opt"; show_help="yes"
327 330
  ;;
328 331
  esac
......
669 672
  fi
670 673
fi
671 674

  
675
##########################################
676
# curses probe
677

  
678
if test "$curses" = "yes" ; then
679
  curses=no
680
  cat > $TMPC << EOF
681
#include <curses.h>
682
int main(void) { return curses_version(); }
683
EOF
684
  if $cc -o $TMPE $TMPC -lcurses 2> /dev/null ; then
685
    curses=yes
686
  fi
687
fi # test "$curses"
688

  
672 689
# Check if tools are available to build documentation.
673 690
if [ -x "`which texi2html 2>/dev/null`" ] && \
674 691
   [ -x "`which pod2man 2>/dev/null`" ]; then
......
720 737
if test "$sdl" != "no" ; then
721 738
    echo "SDL static link   $sdl_static"
722 739
fi
740
echo "curses support    $curses"
723 741
echo "mingw32 support   $mingw32"
724 742
echo "Adlib support     $adlib"
725 743
echo "AC97 support      $ac97"
......
974 992
  fi
975 993
fi
976 994
if test "$cocoa" = "yes" ; then
977
    echo "#define CONFIG_COCOA 1" >> $config_h
978
    echo "CONFIG_COCOA=yes" >> $config_mak
995
  echo "#define CONFIG_COCOA 1" >> $config_h
996
  echo "CONFIG_COCOA=yes" >> $config_mak
997
fi
998
if test "$curses" = "yes" ; then
999
  echo "#define CONFIG_CURSES 1" >> $config_h
1000
  echo "CONFIG_CURSES=yes" >> $config_mak
1001
  echo "CURSES_LIBS=-lcurses" >> $config_mak
979 1002
fi
980 1003

  
981 1004
# XXX: suppress that
......
1040 1063
        -a "$sdl" = "no" -a "$cocoa" = "no" ; then
1041 1064
    echo "ERROR: QEMU requires SDL or Cocoa for graphical output"
1042 1065
    echo "To build QEMU without graphical output configure with --disable-gfx-check"
1043
    echo "Note that this will disable all output from the virtual graphics card."
1066
    echo "Note that this will disable all output from the virtual graphics card"
1067
    echo "except through VNC or curses."
1044 1068
    exit 1;
1045 1069
fi
1046 1070

  
b/console.c
121 121
    vga_hw_update_ptr hw_update;
122 122
    vga_hw_invalidate_ptr hw_invalidate;
123 123
    vga_hw_screen_dump_ptr hw_screen_dump;
124
    vga_hw_text_update_ptr hw_text_update;
124 125
    void *hw;
125 126

  
126 127
    int g_width, g_height;
......
135 136
    TextAttributes t_attrib_default; /* default text attributes */
136 137
    TextAttributes t_attrib; /* currently active text attributes */
137 138
    TextCell *cells;
139
    int text_x[2], text_y[2], cursor_invalidate;
138 140

  
139 141
    enum TTYState state;
140 142
    int esc_params[MAX_ESC_PARAMS];
......
171 173
        consoles[0]->hw_screen_dump(consoles[0]->hw, filename);
172 174
}
173 175

  
176
void vga_hw_text_update(console_ch_t *chardata)
177
{
178
    if (active_console && active_console->hw_text_update)
179
        active_console->hw_text_update(active_console->hw, chardata);
180
}
181

  
174 182
/* convert a RGBA color to a color index usable in graphic primitives */
175 183
static unsigned int vga_get_color(DisplayState *ds, unsigned int rgba)
176 184
{
......
515 523
    s->cells = cells;
516 524
}
517 525

  
526
static inline void text_update_xy(TextConsole *s, int x, int y)
527
{
528
    s->text_x[0] = MIN(s->text_x[0], x);
529
    s->text_x[1] = MAX(s->text_x[1], x);
530
    s->text_y[0] = MIN(s->text_y[0], y);
531
    s->text_y[1] = MAX(s->text_y[1], y);
532
}
533

  
518 534
static void update_xy(TextConsole *s, int x, int y)
519 535
{
520 536
    TextCell *c;
521 537
    int y1, y2;
522 538

  
523 539
    if (s == active_console) {
540
        if (!s->ds->depth) {
541
            text_update_xy(s, x, y);
542
            return;
543
        }
544

  
524 545
        y1 = (s->y_base + y) % s->total_height;
525 546
        y2 = y1 - s->y_displayed;
526 547
        if (y2 < 0)
......
542 563

  
543 564
    if (s == active_console) {
544 565
        int x = s->x;
566

  
567
        if (!s->ds->depth) {
568
            s->cursor_invalidate = 1;
569
            return;
570
        }
571

  
545 572
        if (x >= s->width) {
546 573
            x = s->width - 1;
547 574
        }
......
571 598

  
572 599
    if (s != active_console)
573 600
        return;
601
    if (!s->ds->depth) {
602
        s->text_x[0] = 0;
603
        s->text_y[0] = 0;
604
        s->text_x[1] = s->width - 1;
605
        s->text_y[1] = s->height - 1;
606
        s->cursor_invalidate = 1;
607
        return;
608
    }
574 609

  
575 610
    vga_fill_rect(s->ds, 0, 0, s->ds->width, s->ds->height,
576 611
                  color_table[0][COLOR_BLACK]);
......
648 683
            c++;
649 684
        }
650 685
        if (s == active_console && s->y_displayed == s->y_base) {
686
            if (!s->ds->depth) {
687
                s->text_x[0] = 0;
688
                s->text_y[0] = 0;
689
                s->text_x[1] = s->width - 1;
690
                s->text_y[1] = s->height - 1;
691
                return;
692
            }
693

  
651 694
            vga_bitblt(s->ds, 0, FONT_HEIGHT, 0, 0,
652 695
                       s->width * FONT_WIDTH,
653 696
                       (s->height - 1) * FONT_HEIGHT);
......
998 1041
    s = consoles[index];
999 1042
    if (s) {
1000 1043
        active_console = s;
1001
        if (s->console_type != GRAPHIC_CONSOLE) {
1002
            if (s->g_width != s->ds->width ||
1003
                s->g_height != s->ds->height) {
1004
                if (s->console_type == TEXT_CONSOLE_FIXED_SIZE) {
1005
                    dpy_resize(s->ds, s->g_width, s->g_height);
1006
                } else {
1007
                s->g_width = s->ds->width;
1008
                s->g_height = s->ds->height;
1009
                text_console_resize(s);
1010
            }
1011
            }
1012
            console_refresh(s);
1013
        } else {
1014
            vga_hw_invalidate();
1015
        }
1044
        vga_hw_invalidate();
1016 1045
    }
1017 1046
}
1018 1047

  
......
1116 1145
    }
1117 1146
}
1118 1147

  
1148
static void text_console_invalidate(void *opaque)
1149
{
1150
    TextConsole *s = (TextConsole *) opaque;
1151

  
1152
    if (s->console_type != GRAPHIC_CONSOLE) {
1153
        if (s->g_width != s->ds->width ||
1154
            s->g_height != s->ds->height) {
1155
            if (s->console_type == TEXT_CONSOLE_FIXED_SIZE)
1156
                dpy_resize(s->ds, s->g_width, s->g_height);
1157
            else {
1158
                s->g_width = s->ds->width;
1159
                s->g_height = s->ds->height;
1160
                text_console_resize(s);
1161
            }
1162
        }
1163
    }
1164
    console_refresh(s);
1165
}
1166

  
1167
static void text_console_update(void *opaque, console_ch_t *chardata)
1168
{
1169
    TextConsole *s = (TextConsole *) opaque;
1170
    int i, j, src;
1171

  
1172
    if (s->text_x[0] <= s->text_x[1]) {
1173
        src = (s->y_base + s->text_y[0]) * s->width;
1174
        chardata += s->text_y[0] * s->width;
1175
        for (i = s->text_y[0]; i <= s->text_y[1]; i ++)
1176
            for (j = 0; j < s->width; j ++, src ++)
1177
                console_write_ch(chardata ++, s->cells[src].ch |
1178
                                (s->cells[src].t_attrib.fgcol << 12) |
1179
                                (s->cells[src].t_attrib.bgcol << 8) |
1180
                                (s->cells[src].t_attrib.bold << 21));
1181
        dpy_update(s->ds, s->text_x[0], s->text_y[0],
1182
                   s->text_x[1] - s->text_x[0], i - s->text_y[0]);
1183
        s->text_x[0] = s->width;
1184
        s->text_y[0] = s->height;
1185
        s->text_x[1] = 0;
1186
        s->text_y[1] = 0;
1187
    }
1188
    if (s->cursor_invalidate) {
1189
        dpy_cursor(s->ds, s->x, s->y);
1190
        s->cursor_invalidate = 0;
1191
    }
1192
}
1193

  
1119 1194
static TextConsole *new_console(DisplayState *ds, console_type_t console_type)
1120 1195
{
1121 1196
    TextConsole *s;
......
1150 1225
TextConsole *graphic_console_init(DisplayState *ds, vga_hw_update_ptr update,
1151 1226
                                  vga_hw_invalidate_ptr invalidate,
1152 1227
                                  vga_hw_screen_dump_ptr screen_dump,
1228
                                  vga_hw_text_update_ptr text_update,
1153 1229
                                  void *opaque)
1154 1230
{
1155 1231
    TextConsole *s;
......
1160 1236
    s->hw_update = update;
1161 1237
    s->hw_invalidate = invalidate;
1162 1238
    s->hw_screen_dump = screen_dump;
1239
    s->hw_text_update = text_update;
1163 1240
    s->hw = opaque;
1164 1241
    return s;
1165 1242
}
1166 1243

  
1167 1244
int is_graphic_console(void)
1168 1245
{
1169
    return active_console->console_type == GRAPHIC_CONSOLE;
1246
    return active_console && active_console->console_type == GRAPHIC_CONSOLE;
1170 1247
}
1171 1248

  
1172 1249
void console_color_init(DisplayState *ds)
......
1234 1311
    s->g_width = width;
1235 1312
    s->g_height = height;
1236 1313

  
1314
    s->hw_invalidate = text_console_invalidate;
1315
    s->hw_text_update = text_console_update;
1316
    s->hw = s;
1317

  
1237 1318
    /* Set text attribute defaults */
1238 1319
    s->t_attrib_default.bold = 0;
1239 1320
    s->t_attrib_default.uline = 0;
b/console.h
79 79
                     int dst_x, int dst_y, int w, int h);
80 80
    void (*dpy_fill)(struct DisplayState *s, int x, int y,
81 81
                     int w, int h, uint32_t c);
82
    void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
82 83
    void (*mouse_set)(int x, int y, int on);
83 84
    void (*cursor_define)(int width, int height, int bpp, int hot_x, int hot_y,
84 85
                          uint8_t *image, uint8_t *mask);
......
94 95
    s->dpy_resize(s, w, h);
95 96
}
96 97

  
98
static inline void dpy_cursor(DisplayState *s, int x, int y)
99
{
100
    if (s->dpy_text_cursor)
101
        s->dpy_text_cursor(s, x, y);
102
}
103

  
104
typedef unsigned long console_ch_t;
105
static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
106
{
107
    cpu_to_le32wu((uint32_t *) dest, ch);
108
}
109

  
97 110
typedef void (*vga_hw_update_ptr)(void *);
98 111
typedef void (*vga_hw_invalidate_ptr)(void *);
99 112
typedef void (*vga_hw_screen_dump_ptr)(void *, const char *);
113
typedef void (*vga_hw_text_update_ptr)(void *, console_ch_t *);
100 114

  
101 115
TextConsole *graphic_console_init(DisplayState *ds, vga_hw_update_ptr update,
102 116
                                  vga_hw_invalidate_ptr invalidate,
103 117
                                  vga_hw_screen_dump_ptr screen_dump,
118
                                  vga_hw_text_update_ptr text_update,
104 119
                                  void *opaque);
105 120
void vga_hw_update(void);
106 121
void vga_hw_invalidate(void);
107 122
void vga_hw_screen_dump(const char *filename);
123
void vga_hw_text_update(console_ch_t *chardata);
108 124

  
109 125
int is_graphic_console(void);
110 126
CharDriverState *text_console_init(DisplayState *ds, const char *p);
......
124 140
int vnc_display_password(DisplayState *ds, const char *password);
125 141
void do_info_vnc(void);
126 142

  
143
/* curses.c */
144
void curses_display_init(DisplayState *ds, int full_screen);
145

  
127 146
/* x_keymap.c */
128 147
extern uint8_t _translate_keycode(const int key);
129 148

  
b/curses.c
1
/*
2
 * QEMU curses/ncurses display driver
3
 * 
4
 * Copyright (c) 2005 Andrzej Zaborowski  <balrog@zabor.org>
5
 * 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24

  
25
#include "qemu-common.h"
26
#include "console.h"
27
#include "sysemu.h"
28

  
29
#include <curses.h>
30

  
31
#ifndef _WIN32
32
#include <signal.h>
33
#include <sys/ioctl.h>
34
#include <termios.h>
35
#endif
36

  
37
#define FONT_HEIGHT 16
38
#define FONT_WIDTH 8
39

  
40
static console_ch_t screen[160 * 100];
41
static WINDOW *screenpad = NULL;
42
static int width, height, gwidth, gheight, invalidate;
43
static int px, py, sminx, sminy, smaxx, smaxy;
44

  
45
static void curses_update(DisplayState *ds, int x, int y, int w, int h)
46
{
47
    chtype *line;
48

  
49
    line = ((chtype *) screen) + y * width;
50
    for (h += y; y < h; y ++, line += width)
51
        mvwaddchnstr(screenpad, y, 0, line, width);
52

  
53
    pnoutrefresh(screenpad, py, px, sminy, sminx, smaxy - 1, smaxx - 1);
54
    refresh();
55
}
56

  
57
static void curses_calc_pad(void)
58
{
59
    if (is_graphic_console()) {
60
        width = gwidth;
61
        height = gheight;
62
    } else {
63
        width = COLS;
64
        height = LINES;
65
    }
66

  
67
    if (screenpad)
68
        delwin(screenpad);
69

  
70
    clear();
71
    refresh();
72

  
73
    screenpad = newpad(height, width);
74

  
75
    if (width > COLS) {
76
        px = (width - COLS) / 2;
77
        sminx = 0;
78
        smaxx = COLS;
79
    } else {
80
        px = 0;
81
        sminx = (COLS - width) / 2;
82
        smaxx = sminx + width;
83
    }
84

  
85
    if (height > LINES) {
86
        py = (height - LINES) / 2;
87
        sminy = 0;
88
        smaxy = LINES;
89
    } else {
90
        py = 0;
91
        sminy = (LINES - height) / 2;
92
        smaxy = sminy + height;
93
    }
94
}
95

  
96
static void curses_resize(DisplayState *ds, int w, int h)
97
{
98
    if (w == gwidth && h == gheight)
99
        return;
100

  
101
    gwidth = w;
102
    gheight = h;
103

  
104
    curses_calc_pad();
105
}
106

  
107
#ifndef _WIN32
108
#ifdef SIGWINCH
109
static void curses_winch_handler(int signum)
110
{
111
    struct winsize {
112
        unsigned short ws_row;
113
        unsigned short ws_col;
114
        unsigned short ws_xpixel;   /* unused */
115
        unsigned short ws_ypixel;   /* unused */
116
    } ws;
117

  
118
    /* terminal size changed */
119
    if (ioctl(1, TIOCGWINSZ, &ws) == -1)
120
        return;
121

  
122
    resize_term(ws.ws_row, ws.ws_col);
123
    curses_calc_pad();
124
    invalidate = 1;
125

  
126
    /* some systems require this */
127
    signal(SIGWINCH, curses_winch_handler);
128
}
129
#endif
130
#endif
131

  
132
static void curses_cursor_position(DisplayState *ds, int x, int y)
133
{
134
    if (x >= 0) {
135
        x = sminx + x - px;
136
        y = sminy + y - py;
137

  
138
        if (x >= 0 && y >= 0 && x < COLS && y < LINES) {
139
            move(y, x);
140
            curs_set(1);
141
            /* it seems that curs_set(1) must always be called before
142
             * curs_set(2) for the latter to have effect */
143
            if (!is_graphic_console())
144
                curs_set(2);
145
            return;
146
        }
147
    }
148

  
149
    curs_set(0);
150
}
151

  
152
/* generic keyboard conversion */
153

  
154
#include "curses_keys.h"
155
#include "keymaps.c"
156

  
157
static kbd_layout_t *kbd_layout = 0;
158
static int keycode2keysym[CURSES_KEYS];
159

  
160
static void curses_refresh(DisplayState *ds)
161
{
162
    int chr, nextchr, keysym, keycode;
163

  
164
    if (invalidate) {
165
        clear();
166
        refresh();
167
        curses_calc_pad();
168
        ds->width = FONT_WIDTH * width;
169
        ds->height = FONT_HEIGHT * height;
170
        vga_hw_invalidate();
171
        invalidate = 0;
172
    }
173

  
174
    vga_hw_text_update(screen);
175

  
176
    nextchr = ERR;
177
    while (1) {
178
        /* while there are any pending key strokes to process */
179
        if (nextchr == ERR)
180
            chr = getch();
181
        else {
182
            chr = nextchr;
183
            nextchr = ERR;
184
        }
185

  
186
        if (chr == ERR)
187
            break;
188

  
189
        /* this shouldn't occur when we use a custom SIGWINCH handler */
190
        if (chr == KEY_RESIZE) {
191
            clear();
192
            refresh();
193
            curses_calc_pad();
194
            curses_update(ds, 0, 0, width, height);
195
            ds->width = FONT_WIDTH * width;
196
            ds->height = FONT_HEIGHT * height;
197
            continue;
198
        }
199

  
200
        keycode = curses2keycode[chr];
201
        if (keycode == -1)
202
            continue;
203

  
204
        /* alt key */
205
        if (keycode == 1) {
206
            nextchr = getch();
207

  
208
            if (nextchr != ERR) {
209
                keycode = curses2keycode[nextchr];
210
                nextchr = ERR;
211
                if (keycode == -1)
212
                    continue;
213

  
214
                keycode |= ALT;
215

  
216
                /* process keys reserved for qemu */
217
                if (keycode >= QEMU_KEY_CONSOLE0 &&
218
                        keycode < QEMU_KEY_CONSOLE0 + 9) {
219
                    erase();
220
                    wnoutrefresh(stdscr);
221
                    console_select(keycode - QEMU_KEY_CONSOLE0);
222

  
223
                    invalidate = 1;
224
                    continue;
225
                }
226
            }
227
        }
228

  
229
        if (kbd_layout && !(keycode & GREY)) {
230
            keysym = keycode2keysym[keycode & KEY_MASK];
231
            if (keysym == -1)
232
                keysym = chr;
233

  
234
            keycode &= ~KEY_MASK;
235
            keycode |= keysym2scancode(kbd_layout, keysym);
236
        }
237

  
238
        if (is_graphic_console()) {
239
            /* since terminals don't know about key press and release
240
             * events, we need to emit both for each key received */
241
            if (keycode & SHIFT)
242
                kbd_put_keycode(SHIFT_CODE);
243
            if (keycode & CNTRL)
244
                kbd_put_keycode(CNTRL_CODE);
245
            if (keycode & ALT)
246
                kbd_put_keycode(ALT_CODE);
247
            if (keycode & GREY)
248
                kbd_put_keycode(GREY_CODE);
249
            kbd_put_keycode(keycode & KEY_MASK);
250
            if (keycode & GREY)
251
                kbd_put_keycode(GREY_CODE);
252
            kbd_put_keycode((keycode & KEY_MASK) | KEY_RELEASE);
253
            if (keycode & ALT)
254
                kbd_put_keycode(ALT_CODE | KEY_RELEASE);
255
            if (keycode & CNTRL)
256
                kbd_put_keycode(CNTRL_CODE | KEY_RELEASE);
257
            if (keycode & SHIFT)
258
                kbd_put_keycode(SHIFT_CODE | KEY_RELEASE);
259
        } else {
260
            keysym = curses2keysym[chr];
261
            if (keysym == -1)
262
                keysym = chr;
263

  
264
            kbd_put_keysym(keysym);
265
        }
266
    }
267
}
268

  
269
static void curses_cleanup(void *opaque) 
270
{
271
    endwin();
272
}
273

  
274
static void curses_atexit(void)
275
{
276
    curses_cleanup(NULL);
277
}
278

  
279
static void curses_setup(void)
280
{
281
    int i, colour_default[8] = {
282
        COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN,
283
        COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE,
284
    };
285

  
286
    /* input as raw as possible, let everything be interpreted
287
     * by the guest system */
288
    initscr(); noecho(); intrflush(stdscr, FALSE);
289
    nodelay(stdscr, TRUE); nonl(); keypad(stdscr, TRUE);
290
    start_color(); raw(); scrollok(stdscr, FALSE);
291

  
292
    for (i = 0; i < 64; i ++)
293
        init_pair(i, colour_default[i & 7], colour_default[i >> 3]);
294
}
295

  
296
static void curses_keyboard_setup(void)
297
{
298
    int i, keycode, keysym;
299

  
300
#if defined(__APPLE__)
301
    /* always use generic keymaps */
302
    if (!keyboard_layout)
303
        keyboard_layout = "en-us";
304
#endif
305
    if(keyboard_layout) {
306
        kbd_layout = init_keyboard_layout(keyboard_layout);
307
        if (!kbd_layout)
308
            exit(1);
309
    }
310

  
311
    for (i = 0; i < CURSES_KEYS; i ++)
312
        keycode2keysym[i] = -1;
313

  
314
    for (i = 0; i < CURSES_KEYS; i ++) {
315
        if (curses2keycode[i] == -1)
316
            continue;
317

  
318
        keycode = curses2keycode[i] & KEY_MASK;
319
        if (keycode2keysym[keycode] >= 0)
320
            continue;
321

  
322
        for (keysym = 0; keysym < CURSES_KEYS; keysym ++)
323
            if (curses2keycode[keysym] == keycode) {
324
                keycode2keysym[keycode] = keysym;
325
                break;
326
            }
327

  
328
        if (keysym >= CURSES_KEYS)
329
            keycode2keysym[keycode] = i;
330
    }
331
}
332

  
333
void curses_display_init(DisplayState *ds, int full_screen)
334
{
335
#ifndef _WIN32
336
    if (!isatty(1)) {
337
        fprintf(stderr, "We need a terminal output\n");
338
        exit(1);
339
    }
340
#endif
341

  
342
    curses_setup();
343
    curses_keyboard_setup();
344
    atexit(curses_atexit);
345

  
346
#ifndef _WIN32
347
    signal(SIGINT, SIG_DFL);
348
    signal(SIGQUIT, SIG_DFL);
349
#ifdef SIGWINCH
350
    /* some curses implementations provide a handler, but we
351
     * want to be sure this is handled regardless of the library */
352
    signal(SIGWINCH, curses_winch_handler);
353
#endif
354
#endif
355

  
356
    ds->data = (void *) screen;
357
    ds->linesize = 0;
358
    ds->depth = 0;
359
    ds->width = 640;
360
    ds->height = 400;
361
    ds->dpy_update = curses_update;
362
    ds->dpy_resize = curses_resize;
363
    ds->dpy_refresh = curses_refresh;
364
    ds->dpy_text_cursor = curses_cursor_position;
365

  
366
    invalidate = 1;
367

  
368
    /* Standard VGA initial text mode dimensions */
369
    curses_resize(ds, 80, 25);
370
}
b/curses_keys.h
1
/*
2
 * Keycode and keysyms conversion tables for curses
3
 * 
4
 * Copyright (c) 2005 Andrzej Zaborowski  <balrog@zabor.org>
5
 * 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
#define KEY_RELEASE         0x80
25
#define KEY_MASK            0x7f
26
#define SHIFT_CODE          0x2a
27
#define SHIFT               0x0080
28
#define GREY_CODE           0xe0
29
#define GREY                0x0100
30
#define CNTRL_CODE          0x1d
31
#define CNTRL               0x0200
32
#define ALT_CODE            0x38
33
#define ALT                 0x0400
34

  
35
/* curses won't detect a Control + Alt + 1, so use Alt + 1 */
36
#define QEMU_KEY_CONSOLE0   (2 | ALT)   /* (curses2keycode['1'] | ALT) */
37

  
38
#define CURSES_KEYS         KEY_MAX     /* KEY_MAX defined in <curses.h> */
39

  
40
int curses2keycode[CURSES_KEYS] = {
41
    [0 ... (CURSES_KEYS - 1)] = -1,
42

  
43
    [0x01b] = 1, /* Escape */
44
    ['1'] = 2,
45
    ['2'] = 3,
46
    ['3'] = 4,
47
    ['4'] = 5,
48
    ['5'] = 6,
49
    ['6'] = 7,
50
    ['7'] = 8,
51
    ['8'] = 9,
52
    ['9'] = 10,
53
    ['0'] = 11,
54
    ['-'] = 12,
55
    ['='] = 13,
56
    [0x07f] = 14, /* Backspace */
57
    [0x107] = 14, /* Backspace */
58

  
59
    ['\t'] = 15, /* Tab */
60
    ['q'] = 16,
61
    ['w'] = 17,
62
    ['e'] = 18,
63
    ['r'] = 19,
64
    ['t'] = 20,
65
    ['y'] = 21,
66
    ['u'] = 22,
67
    ['i'] = 23,
68
    ['o'] = 24,
69
    ['p'] = 25,
70
    ['['] = 26,
71
    [']'] = 27,
72
    ['\n'] = 28, /* Return */
73
    ['\r'] = 28, /* Return */
74
    [0x157] = 28, /* Return */
75

  
76
    ['a'] = 30,
77
    ['s'] = 31,
78
    ['d'] = 32,
79
    ['f'] = 33,
80
    ['g'] = 34,
81
    ['h'] = 35,
82
    ['j'] = 36,
83
    ['k'] = 37,
84
    ['l'] = 38,
85
    [';'] = 39,
86
    ['\''] = 40, /* Single quote */
87
    ['`'] = 41,
88
    ['\\'] = 43, /* Backslash */
89

  
90
    ['z'] = 44,
91
    ['x'] = 45,
92
    ['c'] = 46,
93
    ['v'] = 47,
94
    ['b'] = 48,
95
    ['n'] = 49,
96
    ['m'] = 50,
97
    [','] = 51,
98
    ['.'] = 52,
99
    ['/'] = 53,
100

  
101
    [' '] = 57,
102

  
103
    [0x109] = 59, /* Function Key 1 */
104
    [0x10a] = 60, /* Function Key 2 */
105
    [0x10b] = 61, /* Function Key 3 */
106
    [0x10c] = 62, /* Function Key 4 */
107
    [0x10d] = 63, /* Function Key 5 */
108
    [0x10e] = 64, /* Function Key 6 */
109
    [0x10f] = 65, /* Function Key 7 */
110
    [0x110] = 66, /* Function Key 8 */
111
    [0x111] = 67, /* Function Key 9 */
112
    [0x112] = 68, /* Function Key 10 */
113
    [0x113] = 87, /* Function Key 11 */
114
    [0x114] = 88, /* Function Key 12 */
115

  
116
    [0x106] = 71 | GREY, /* Home */
117
    [0x103] = 72 | GREY, /* Up Arrow */
118
    [0x153] = 73 | GREY, /* Page Up */
119
    [0x104] = 75 | GREY, /* Left Arrow */
120
    [0x105] = 77 | GREY, /* Right Arrow */
121
    [0x168] = 79 | GREY, /* End */
122
    [0x102] = 80 | GREY, /* Down Arrow */
123
    [0x152] = 81 | GREY, /* Page Down */
124
    [0x14b] = 82 | GREY, /* Insert */
125
    [0x14a] = 83 | GREY, /* Delete */
126

  
127
    ['!'] = 2 | SHIFT,
128
    ['@'] = 3 | SHIFT,
129
    ['#'] = 4 | SHIFT,
130
    ['$'] = 5 | SHIFT,
131
    ['%'] = 6 | SHIFT,
132
    ['^'] = 7 | SHIFT,
133
    ['&'] = 8 | SHIFT,
134
    ['*'] = 9 | SHIFT,
135
    ['('] = 10 | SHIFT,
136
    [')'] = 11 | SHIFT,
137
    ['_'] = 12 | SHIFT,
138
    ['+'] = 13 | SHIFT,
139

  
140
    [0x161] = 15 | SHIFT, /* Shift + Tab */
141
    ['Q'] = 16 | SHIFT,
142
    ['W'] = 17 | SHIFT,
143
    ['E'] = 18 | SHIFT,
144
    ['R'] = 19 | SHIFT,
145
    ['T'] = 20 | SHIFT,
146
    ['Y'] = 21 | SHIFT,
147
    ['U'] = 22 | SHIFT,
148
    ['I'] = 23 | SHIFT,
149
    ['O'] = 24 | SHIFT,
150
    ['P'] = 25 | SHIFT,
151
    ['{'] = 26 | SHIFT,
152
    ['}'] = 27 | SHIFT,
153

  
154
    ['A'] = 30 | SHIFT,
155
    ['S'] = 31 | SHIFT,
156
    ['D'] = 32 | SHIFT,
157
    ['F'] = 33 | SHIFT,
158
    ['G'] = 34 | SHIFT,
159
    ['H'] = 35 | SHIFT,
160
    ['J'] = 36 | SHIFT,
161
    ['K'] = 37 | SHIFT,
162
    ['L'] = 38 | SHIFT,
163
    [':'] = 39 | SHIFT,
164
    ['"'] = 40 | SHIFT,
165
    ['~'] = 41 | SHIFT,
166
    ['|'] = 43 | SHIFT,
167

  
168
    ['Z'] = 44 | SHIFT,
169
    ['X'] = 45 | SHIFT,
170
    ['C'] = 46 | SHIFT,
171
    ['V'] = 47 | SHIFT,
172
    ['B'] = 48 | SHIFT,
173
    ['N'] = 49 | SHIFT,
174
    ['M'] = 50 | SHIFT,
175
    ['<'] = 51 | SHIFT,
176
    ['>'] = 52 | SHIFT,
177
    ['?'] = 53 | SHIFT,
178

  
179
    [0x115] = 59 | SHIFT, /* Shift + Function Key 1 */
180
    [0x116] = 60 | SHIFT, /* Shift + Function Key 2 */
181
    [0x117] = 61 | SHIFT, /* Shift + Function Key 3 */
182
    [0x118] = 62 | SHIFT, /* Shift + Function Key 4 */
183
    [0x119] = 63 | SHIFT, /* Shift + Function Key 5 */
184
    [0x11a] = 64 | SHIFT, /* Shift + Function Key 6 */
185
    [0x11b] = 65 | SHIFT, /* Shift + Function Key 7 */
186
    [0x11c] = 66 | SHIFT, /* Shift + Function Key 8 */
187

  
188
    [0x011] = 16 | CNTRL, /* Control + q */
189
    [0x017] = 17 | CNTRL, /* Control + w */
190
    [0x005] = 18 | CNTRL, /* Control + e */
191
    [0x012] = 19 | CNTRL, /* Control + r */
192
    [0x014] = 20 | CNTRL, /* Control + t */
193
    [0x019] = 21 | CNTRL, /* Control + y */
194
    [0x015] = 22 | CNTRL, /* Control + u */
195
    [0x009] = 23 | CNTRL, /* Control + i */
196
    [0x00f] = 24 | CNTRL, /* Control + o */
197
    [0x010] = 25 | CNTRL, /* Control + p */
198

  
199
    [0x001] = 30 | CNTRL, /* Control + a */
200
    [0x013] = 31 | CNTRL, /* Control + s */
201
    [0x014] = 32 | CNTRL, /* Control + d */
202
    [0x006] = 33 | CNTRL, /* Control + f */
203
    [0x007] = 34 | CNTRL, /* Control + g */
204
    [0x008] = 35 | CNTRL, /* Control + h */
205
    [0x00a] = 36 | CNTRL, /* Control + j */
206
    [0x00b] = 37 | CNTRL, /* Control + k */
207
    [0x00c] = 38 | CNTRL, /* Control + l */
208

  
209
    [0x01a] = 44 | CNTRL, /* Control + z */
210
    [0x018] = 45 | CNTRL, /* Control + x */
211
    [0x003] = 46 | CNTRL, /* Control + c */
212
    [0x016] = 47 | CNTRL, /* Control + v */
213
    [0x002] = 48 | CNTRL, /* Control + b */
214
    [0x00e] = 49 | CNTRL, /* Control + n */
215
    /* Control + m collides with the keycode for Enter */
216

  
217
};
218

  
219
int curses2keysym[CURSES_KEYS] = {
220
    [0 ... (CURSES_KEYS - 1)] = -1,
221

  
222
    ['\n'] = '\n',
223
    ['\r'] = '\n',
224

  
225
    [0x07f] = QEMU_KEY_BACKSPACE,
226

  
227
    [0x102] = QEMU_KEY_DOWN,
228
    [0x103] = QEMU_KEY_UP,
229
    [0x104] = QEMU_KEY_LEFT,
230
    [0x105] = QEMU_KEY_RIGHT,
231
    [0x106] = QEMU_KEY_HOME,
232
    [0x107] = QEMU_KEY_BACKSPACE,
233

  
234
    [0x14a] = QEMU_KEY_DELETE,
235
    [0x152] = QEMU_KEY_PAGEDOWN,
236
    [0x153] = QEMU_KEY_PAGEUP,
237
    [0x157] = '\n',
238
    [0x168] = QEMU_KEY_END,
239

  
240
};
241

  
242
typedef struct {
243
	const char* name;
244
	int keysym;
245
} name2keysym_t;
246

  
247
static name2keysym_t name2keysym[] = {
248
    /* Plain ASCII */
249
    { "space", 0x020 },
250
    { "exclam", 0x021 },
251
    { "quotedbl", 0x022 },
252
    { "numbersign", 0x023 },
253
    { "dollar", 0x024 },
254
    { "percent", 0x025 },
255
    { "ampersand", 0x026 },
256
    { "apostrophe", 0x027 },
257
    { "parenleft", 0x028 },
258
    { "parenright", 0x029 },
259
    { "asterisk", 0x02a },
260
    { "plus", 0x02b },
261
    { "comma", 0x02c },
262
    { "minus", 0x02d },
263
    { "period", 0x02e },
264
    { "slash", 0x02f },
265
    { "0", 0x030 },
266
    { "1", 0x031 },
267
    { "2", 0x032 },
268
    { "3", 0x033 },
269
    { "4", 0x034 },
270
    { "5", 0x035 },
271
    { "6", 0x036 },
272
    { "7", 0x037 },
273
    { "8", 0x038 },
274
    { "9", 0x039 },
275
    { "colon", 0x03a },
276
    { "semicolon", 0x03b },
277
    { "less", 0x03c },
278
    { "equal", 0x03d },
279
    { "greater", 0x03e },
280
    { "question", 0x03f },
281
    { "at", 0x040 },
282
    { "A", 0x041 },
283
    { "B", 0x042 },
284
    { "C", 0x043 },
285
    { "D", 0x044 },
286
    { "E", 0x045 },
287
    { "F", 0x046 },
288
    { "G", 0x047 },
289
    { "H", 0x048 },
290
    { "I", 0x049 },
291
    { "J", 0x04a },
292
    { "K", 0x04b },
293
    { "L", 0x04c },
294
    { "M", 0x04d },
295
    { "N", 0x04e },
296
    { "O", 0x04f },
297
    { "P", 0x050 },
298
    { "Q", 0x051 },
299
    { "R", 0x052 },
300
    { "S", 0x053 },
301
    { "T", 0x054 },
302
    { "U", 0x055 },
303
    { "V", 0x056 },
304
    { "W", 0x057 },
305
    { "X", 0x058 },
306
    { "Y", 0x059 },
307
    { "Z", 0x05a },
308
    { "bracketleft", 0x05b },
309
    { "backslash", 0x05c },
310
    { "bracketright", 0x05d },
311
    { "asciicircum", 0x05e },
312
    { "underscore", 0x05f },
313
    { "grave", 0x060 },
314
    { "a", 0x061 },
315
    { "b", 0x062 },
316
    { "c", 0x063 },
317
    { "d", 0x064 },
318
    { "e", 0x065 },
319
    { "f", 0x066 },
320
    { "g", 0x067 },
321
    { "h", 0x068 },
322
    { "i", 0x069 },
323
    { "j", 0x06a },
324
    { "k", 0x06b },
325
    { "l", 0x06c },
326
    { "m", 0x06d },
327
    { "n", 0x06e },
328
    { "o", 0x06f },
329
    { "p", 0x070 },
330
    { "q", 0x071 },
331
    { "r", 0x072 },
332
    { "s", 0x073 },
333
    { "t", 0x074 },
334
    { "u", 0x075 },
335
    { "v", 0x076 },
336
    { "w", 0x077 },
337
    { "x", 0x078 },
338
    { "y", 0x079 },
339
    { "z", 0x07a },
340
    { "braceleft", 0x07b },
341
    { "bar", 0x07c },
342
    { "braceright", 0x07d },
343
    { "asciitilde", 0x07e },
344

  
345
    /* Latin-1 extensions */
346
    { "nobreakspace", 0x0a0 },
347
    { "exclamdown", 0x0a1 },
348
    { "cent", 0x0a2 },
349
    { "sterling", 0x0a3 },
350
    { "currency", 0x0a4 },
351
    { "yen", 0x0a5 },
352
    { "brokenbar", 0x0a6 },
353
    { "section", 0x0a7 },
354
    { "diaeresis", 0x0a8 },
355
    { "copyright", 0x0a9 },
356
    { "ordfeminine", 0x0aa },
357
    { "guillemotleft", 0x0ab },
358
    { "notsign", 0x0ac },
359
    { "hyphen", 0x0ad },
360
    { "registered", 0x0ae },
361
    { "macron", 0x0af },
362
    { "degree", 0x0b0 },
363
    { "plusminus", 0x0b1 },
364
    { "twosuperior", 0x0b2 },
365
    { "threesuperior", 0x0b3 },
366
    { "acute", 0x0b4 },
367
    { "mu", 0x0b5 },
368
    { "paragraph", 0x0b6 },
369
    { "periodcentered", 0x0b7 },
370
    { "cedilla", 0x0b8 },
371
    { "onesuperior", 0x0b9 },
372
    { "masculine", 0x0ba },
373
    { "guillemotright", 0x0bb },
374
    { "onequarter", 0x0bc },
375
    { "onehalf", 0x0bd },
376
    { "threequarters", 0x0be },
377
    { "questiondown", 0x0bf },
378
    { "Agrave", 0x0c0 },
379
    { "Aacute", 0x0c1 },
380
    { "Acircumflex", 0x0c2 },
381
    { "Atilde", 0x0c3 },
382
    { "Adiaeresis", 0x0c4 },
383
    { "Aring", 0x0c5 },
384
    { "AE", 0x0c6 },
385
    { "Ccedilla", 0x0c7 },
386
    { "Egrave", 0x0c8 },
387
    { "Eacute", 0x0c9 },
388
    { "Ecircumflex", 0x0ca },
389
    { "Ediaeresis", 0x0cb },
390
    { "Igrave", 0x0cc },
391
    { "Iacute", 0x0cd },
392
    { "Icircumflex", 0x0ce },
393
    { "Idiaeresis", 0x0cf },
394
    { "ETH", 0x0d0 },
395
    { "Eth", 0x0d0 },
396
    { "Ntilde", 0x0d1 },
397
    { "Ograve", 0x0d2 },
398
    { "Oacute", 0x0d3 },
399
    { "Ocircumflex", 0x0d4 },
400
    { "Otilde", 0x0d5 },
401
    { "Odiaeresis", 0x0d6 },
402
    { "multiply", 0x0d7 },
403
    { "Ooblique", 0x0d8 },
404
    { "Oslash", 0x0d8 },
405
    { "Ugrave", 0x0d9 },
406
    { "Uacute", 0x0da },
407
    { "Ucircumflex", 0x0db },
408
    { "Udiaeresis", 0x0dc },
409
    { "Yacute", 0x0dd },
410
    { "THORN", 0x0de },
411
    { "Thorn", 0x0de },
412
    { "ssharp", 0x0df },
413
    { "agrave", 0x0e0 },
414
    { "aacute", 0x0e1 },
415
    { "acircumflex", 0x0e2 },
416
    { "atilde", 0x0e3 },
417
    { "adiaeresis", 0x0e4 },
418
    { "aring", 0x0e5 },
419
    { "ae", 0x0e6 },
420
    { "ccedilla", 0x0e7 },
421
    { "egrave", 0x0e8 },
422
    { "eacute", 0x0e9 },
423
    { "ecircumflex", 0x0ea },
424
    { "ediaeresis", 0x0eb },
425
    { "igrave", 0x0ec },
426
    { "iacute", 0x0ed },
427
    { "icircumflex", 0x0ee },
428
    { "idiaeresis", 0x0ef },
429
    { "eth", 0x0f0 },
430
    { "ntilde", 0x0f1 },
431
    { "ograve", 0x0f2 },
432
    { "oacute", 0x0f3 },
433
    { "ocircumflex", 0x0f4 },
434
    { "otilde", 0x0f5 },
435
    { "odiaeresis", 0x0f6 },
436
    { "division", 0x0f7 },
437
    { "oslash", 0x0f8 },
438
    { "ooblique", 0x0f8 },
439
    { "ugrave", 0x0f9 },
440
    { "uacute", 0x0fa },
441
    { "ucircumflex", 0x0fb },
442
    { "udiaeresis", 0x0fc },
443
    { "yacute", 0x0fd },
444
    { "thorn", 0x0fe },
445
    { "ydiaeresis", 0x0ff },
446

  
447
    /* Special keys */
448
    { "BackSpace", 0x07f },
449
    { "Tab", '\t' },
450
    { "Return", '\r' },
451
    { "Right", 0x105 },
452
    { "Left", 0x104 },
453
    { "Up", 0x103 },
454
    { "Down", 0x102 },
455
    { "Page_Down", 0x152 },
456
    { "Page_Up", 0x153 },
457
    { "Insert", 0x14b },
458
    { "Delete", 0x14a },
459
    { "Home", 0x106 },
460
    { "End", 0x168 },
461
    { "F1", 0x109 },
462
    { "F2", 0x10a },
463
    { "F3", 0x10b },
464
    { "F4", 0x10c },
465
    { "F5", 0x10d },
466
    { "F6", 0x10e },
467
    { "F7", 0x10f },
468
    { "F8", 0x110 },
469
    { "F9", 0x111 },
470
    { "F10", 0x112 },
471
    { "F11", 0x113 },
472
    { "F12", 0x114 },
473
    { "F13", 0x115 },
474
    { "F14", 0x116 },
475
    { "F15", 0x117 },
476
    { "F16", 0x118 },
477
    { "F17", 0x119 },
478
    { "F18", 0x11a },
479
    { "F19", 0x11b },
480
    { "F20", 0x11c },
481
    { "Escape", 27 },
482

  
483
    { 0, 0 },
484
};
b/hw/cirrus_vga.c
3257 3257
                    ds, vga_ram_base, vga_ram_offset, vga_ram_size);
3258 3258
    cirrus_init_common(s, device_id, 1);
3259 3259

  
3260
    graphic_console_init(s->ds, s->update, s->invalidate, s->screen_dump, s);
3260
    graphic_console_init(s->ds, s->update, s->invalidate, s->screen_dump,
3261
                         s->text_update, s);
3261 3262

  
3262 3263
    s->pci_dev = (PCIDevice *)d;
3263 3264

  
b/hw/jazz_led.c
285 285
    printf("jazz_led_screen_dump() not implemented\n");
286 286
}
287 287

  
288
static void jazz_led_text_update(void *opaque, console_ch_t *chardata)
289
{
290
    LedState *s = opaque;
291
    char buf[2];
292

  
293
    dpy_cursor(s->ds, -1, -1);
294
    dpy_resize(s->ds, 2, 1);
295

  
296
    /* TODO: draw the segments */
297
    snprintf(buf, 2, "%02hhx\n", s->segments);
298
    console_write_ch(chardata++, 0x00200100 | buf[0]);
299
    console_write_ch(chardata++, 0x00200100 | buf[1]);
300

  
301
    dpy_update(s->ds, 0, 0, 2, 1);
302
}
303

  
288 304
void jazz_led_init(DisplayState *ds, target_phys_addr_t base)
289 305
{
290 306
    LedState *s;
......
301 317
    io = cpu_register_io_memory(0, led_read, led_write, s);
302 318
    cpu_register_physical_memory(s->base, 1, io);
303 319

  
304
    graphic_console_init(ds, jazz_led_update_display, jazz_led_invalidate_display, jazz_led_screen_dump, s);
320
    graphic_console_init(ds, jazz_led_update_display,
321
                         jazz_led_invalidate_display, jazz_led_screen_dump,
322
                         jazz_led_text_update, s);
305 323
}
b/hw/omap_lcdc.c
495 495
    cpu_register_physical_memory(s->base, 0x100, iomemtype);
496 496

  
497 497
    graphic_console_init(ds, omap_update_display,
498
                    omap_invalidate_display, omap_screen_dump, s);
498
                    omap_invalidate_display, omap_screen_dump, NULL, s);
499 499

  
500 500
    return s;
501 501
}
b/hw/pl110.c
426 426
    s->versatile = versatile;
427 427
    s->irq = irq;
428 428
    graphic_console_init(ds, pl110_update_display, pl110_invalidate_display,
429
                         NULL, s);
429
                         NULL, NULL, s);
430 430
    /* ??? Save/restore.  */
431 431
    return s;
432 432
}
b/hw/pxa2xx_lcd.c
1002 1002
    cpu_register_physical_memory(base, 0x00100000, iomemtype);
1003 1003

  
1004 1004
    graphic_console_init(ds, pxa2xx_update_display,
1005
                    pxa2xx_invalidate_display, pxa2xx_screen_dump, s);
1005
                    pxa2xx_invalidate_display, pxa2xx_screen_dump, NULL, s);
1006 1006

  
1007 1007
    switch (s->ds->depth) {
1008 1008
    case 0:
b/hw/ssd0303.c
270 270
    s->i2c.recv = ssd0303_recv;
271 271
    s->i2c.send = ssd0303_send;
272 272
    graphic_console_init(ds, ssd0303_update_display, ssd0303_invalidate_display,
273
                         NULL, s);
273
                         NULL, NULL, s);
274 274
    dpy_resize(s->ds, 96 * MAGNIFY, 16 * MAGNIFY);
275 275
}
b/hw/ssd0323.c
280 280
    s = (ssd0323_state *)qemu_mallocz(sizeof(ssd0323_state));
281 281
    s->ds = ds;
282 282
    graphic_console_init(ds, ssd0323_update_display, ssd0323_invalidate_display,
283
                         NULL, s);
283
                         NULL, NULL, s);
284 284
    dpy_resize(s->ds, 128 * MAGNIFY, 64 * MAGNIFY);
285 285
    s->col_end = 63;
286 286
    s->row_end = 79;
b/hw/tcx.c
537 537
        s->cplane_offset = vram_offset;
538 538
        cpu_register_physical_memory(addr + 0x0a000000ULL, size, vram_offset);
539 539
        graphic_console_init(s->ds, tcx24_update_display,
540
                             tcx24_invalidate_display, tcx24_screen_dump, s);
540
                             tcx24_invalidate_display,
541
                             tcx24_screen_dump, NULL, s);
541 542
    } else {
542 543
        cpu_register_physical_memory(addr + 0x00300000ULL, TCX_THC_NREGS_8,
543 544
                                     dummy_memory);
544 545
        graphic_console_init(s->ds, tcx_update_display, tcx_invalidate_display,
545
                             tcx_screen_dump, s);
546
                             tcx_screen_dump, NULL, s);
546 547
    }
547 548
    // NetBSD writes here even with 8-bit display
548 549
    cpu_register_physical_memory(addr + 0x00301000ULL, TCX_THC_NREGS_24,
b/hw/vga.c
1660 1660
    s->graphic_mode = -1; /* force full update */
1661 1661
}
1662 1662

  
1663
#define TEXTMODE_X(x)	((x) % width)
1664
#define TEXTMODE_Y(x)	((x) / width)
1665
#define VMEM2CHTYPE(v)	((v & 0xff0007ff) | \
1666
        ((v & 0x00000800) << 10) | ((v & 0x00007000) >> 1))
1667
/* relay text rendering to the display driver
1668
 * instead of doing a full vga_update_display() */
1669
static void vga_update_text(void *opaque, console_ch_t *chardata)
1670
{
1671
    VGAState *s = (VGAState *) opaque;
1672
    int graphic_mode, i, cursor_offset, cursor_visible;
1673
    int cw, cheight, width, height, size, c_min, c_max;
1674
    uint32_t *src;
1675
    console_ch_t *dst, val;
1676
    char msg_buffer[80];
1677
    int full_update;
1678
    full_update = 0;
1679

  
1680
    if (!(s->ar_index & 0x20)) {
1681
        graphic_mode = GMODE_BLANK;
1682
    } else {
1683
        graphic_mode = s->gr[6] & 1;
1684
    }
1685
    if (graphic_mode != s->graphic_mode) {
1686
        s->graphic_mode = graphic_mode;
1687
        full_update = 1;
1688
    }
1689
    if (s->last_width == -1) {
1690
        s->last_width = 0;
1691
        full_update = 1;
1692
    }
1693

  
1694
    switch (graphic_mode) {
1695
    case GMODE_TEXT:
1696
        /* TODO: update palette */
1697
        full_update |= update_basic_params(s);
1698

  
1699
        /* total width & height */
1700
        cheight = (s->cr[9] & 0x1f) + 1;
1701
        cw = 8;
1702
        if (!(s->sr[1] & 0x01))
1703
            cw = 9;
1704
        if (s->sr[1] & 0x08)
1705
            cw = 16; /* NOTE: no 18 pixel wide */
1706
        width = (s->cr[0x01] + 1);
1707
        if (s->cr[0x06] == 100) {
1708
            /* ugly hack for CGA 160x100x16 - explain me the logic */
1709
            height = 100;
1710
        } else {
1711
            height = s->cr[0x12] | 
1712
                ((s->cr[0x07] & 0x02) << 7) | 
1713
                ((s->cr[0x07] & 0x40) << 3);
1714
            height = (height + 1) / cheight;
1715
        }
1716

  
1717
        size = (height * width);
1718
        if (size > CH_ATTR_SIZE) {
1719
            if (!full_update)
1720
                return;
1721

  
1722
            sprintf(msg_buffer, "%i x %i Text mode", width, height);
1723
            break;
1724
        }
1725

  
1726
        if (width != s->last_width || height != s->last_height ||
1727
            cw != s->last_cw || cheight != s->last_ch) {
1728
            s->last_scr_width = width * cw;
1729
            s->last_scr_height = height * cheight;
1730
            dpy_resize(s->ds, width, height);
1731
            s->last_width = width;
1732
            s->last_height = height;
1733
            s->last_ch = cheight;
1734
            s->last_cw = cw;
1735
            full_update = 1;
1736
        }
1737

  
1738
        /* Update "hardware" cursor */
1739
        cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr;
1740
        if (cursor_offset != s->cursor_offset ||
1741
            s->cr[0xa] != s->cursor_start ||
1742
            s->cr[0xb] != s->cursor_end || full_update) {
1743
            cursor_visible = !(s->cr[0xa] & 0x20);
1744
            if (cursor_visible && cursor_offset < size && cursor_offset >= 0)
1745
                dpy_cursor(s->ds,
1746
                           TEXTMODE_X(cursor_offset),
1747
                           TEXTMODE_Y(cursor_offset));
1748
            else
1749
                dpy_cursor(s->ds, -1, -1);
1750
            s->cursor_offset = cursor_offset;
1751
            s->cursor_start = s->cr[0xa];
1752
            s->cursor_end = s->cr[0xb];
1753
        }
1754

  
1755
        src = (uint32_t *) s->vram_ptr + s->start_addr;
1756
        dst = chardata;
1757

  
1758
        if (full_update) {
1759
            for (i = 0; i < size; src ++, dst ++, i ++)
1760
                console_write_ch(dst, VMEM2CHTYPE(*src));
1761

  
1762
            dpy_update(s->ds, 0, 0, width, height);
1763
        } else {
1764
            c_max = 0;
1765

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff