* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-
-#include "qemu-common.h"
-#include "console.h"
-#include "sysemu.h"
-
#include <curses.h>
#ifndef _WIN32
#include <termios.h>
#endif
+#ifdef __OpenBSD__
+#define resize_term resizeterm
+#endif
+
+#include "qemu-common.h"
+#include "console.h"
+#include "sysemu.h"
+
#define FONT_HEIGHT 16
#define FONT_WIDTH 8
static void curses_calc_pad(void)
{
- if (is_graphic_console()) {
+ if (is_fixedsize_console()) {
width = gwidth;
height = gheight;
} else {
}
}
-static void curses_resize(DisplayState *ds, int w, int h)
+static void curses_resize(DisplayState *ds)
{
- if (w == gwidth && h == gheight)
+ if (ds_get_width(ds) == gwidth && ds_get_height(ds) == gheight)
return;
- gwidth = w;
- gheight = h;
+ gwidth = ds_get_width(ds);
+ gheight = ds_get_height(ds);
curses_calc_pad();
+ ds->surface->width = width * FONT_WIDTH;
+ ds->surface->height = height * FONT_HEIGHT;
}
#ifndef _WIN32
-#ifdef SIGWINCH
+#if defined(SIGWINCH) && defined(KEY_RESIZE)
static void curses_winch_handler(int signum)
{
struct winsize {
/* generic keyboard conversion */
#include "curses_keys.h"
-#include "keymaps.c"
-static kbd_layout_t *kbd_layout = 0;
-static int keycode2keysym[CURSES_KEYS];
+static kbd_layout_t *kbd_layout = NULL;
static void curses_refresh(DisplayState *ds)
{
- int chr, nextchr, keysym, keycode;
+ int chr, nextchr, keysym, keycode, keycode_alt;
if (invalidate) {
clear();
refresh();
curses_calc_pad();
- ds->width = FONT_WIDTH * width;
- ds->height = FONT_HEIGHT * height;
+ ds->surface->width = FONT_WIDTH * width;
+ ds->surface->height = FONT_HEIGHT * height;
vga_hw_invalidate();
invalidate = 0;
}
if (chr == ERR)
break;
+#ifdef KEY_RESIZE
/* this shouldn't occur when we use a custom SIGWINCH handler */
if (chr == KEY_RESIZE) {
clear();
refresh();
curses_calc_pad();
curses_update(ds, 0, 0, width, height);
- ds->width = FONT_WIDTH * width;
- ds->height = FONT_HEIGHT * height;
+ ds->surface->width = FONT_WIDTH * width;
+ ds->surface->height = FONT_HEIGHT * height;
continue;
}
+#endif
keycode = curses2keycode[chr];
- if (keycode == -1)
- continue;
+ keycode_alt = 0;
/* alt key */
if (keycode == 1) {
nextchr = getch();
if (nextchr != ERR) {
+ chr = nextchr;
+ keycode_alt = ALT;
keycode = curses2keycode[nextchr];
nextchr = ERR;
- if (keycode == -1)
- continue;
- keycode |= ALT;
+ if (keycode != -1) {
+ keycode |= ALT;
- /* process keys reserved for qemu */
- if (keycode >= QEMU_KEY_CONSOLE0 &&
- keycode < QEMU_KEY_CONSOLE0 + 9) {
- erase();
- wnoutrefresh(stdscr);
- console_select(keycode - QEMU_KEY_CONSOLE0);
+ /* process keys reserved for qemu */
+ if (keycode >= QEMU_KEY_CONSOLE0 &&
+ keycode < QEMU_KEY_CONSOLE0 + 9) {
+ erase();
+ wnoutrefresh(stdscr);
+ console_select(keycode - QEMU_KEY_CONSOLE0);
- invalidate = 1;
- continue;
+ invalidate = 1;
+ continue;
+ }
}
}
}
- if (kbd_layout && !(keycode & GREY)) {
- keysym = keycode2keysym[keycode & KEY_MASK];
- if (keysym == -1)
- keysym = chr;
+ if (kbd_layout) {
+ keysym = -1;
+ if (chr < CURSES_KEYS)
+ keysym = curses2keysym[chr];
- keycode &= ~KEY_MASK;
- keycode |= keysym2scancode(kbd_layout, keysym);
+ if (keysym == -1) {
+ if (chr < ' ')
+ keysym = (chr + '@' - 'A' + 'a') | KEYSYM_CNTRL;
+ else
+ keysym = chr;
+ }
+
+ keycode = keysym2scancode(kbd_layout, keysym & KEYSYM_MASK);
+ if (keycode == 0)
+ continue;
+
+ keycode |= (keysym & ~KEYSYM_MASK) >> 16;
+ keycode |= keycode_alt;
}
+ if (keycode == -1)
+ continue;
+
if (is_graphic_console()) {
/* since terminals don't know about key press and release
* events, we need to emit both for each key received */
kbd_put_keycode(CNTRL_CODE);
if (keycode & ALT)
kbd_put_keycode(ALT_CODE);
+ if (keycode & ALTGR) {
+ kbd_put_keycode(SCANCODE_EMUL0);
+ kbd_put_keycode(ALT_CODE);
+ }
if (keycode & GREY)
kbd_put_keycode(GREY_CODE);
kbd_put_keycode(keycode & KEY_MASK);
if (keycode & GREY)
kbd_put_keycode(GREY_CODE);
kbd_put_keycode((keycode & KEY_MASK) | KEY_RELEASE);
+ if (keycode & ALTGR) {
+ kbd_put_keycode(SCANCODE_EMUL0);
+ kbd_put_keycode(ALT_CODE | KEY_RELEASE);
+ }
if (keycode & ALT)
kbd_put_keycode(ALT_CODE | KEY_RELEASE);
if (keycode & CNTRL)
if (keycode & SHIFT)
kbd_put_keycode(SHIFT_CODE | KEY_RELEASE);
} else {
- keysym = curses2keysym[chr];
+ keysym = curses2qemu[chr];
if (keysym == -1)
keysym = chr;
}
}
-static void curses_cleanup(void *opaque)
-{
- endwin();
-}
-
static void curses_atexit(void)
{
- curses_cleanup(NULL);
+ endwin();
}
static void curses_setup(void)
static void curses_keyboard_setup(void)
{
- int i, keycode, keysym;
-
#if defined(__APPLE__)
/* always use generic keymaps */
if (!keyboard_layout)
keyboard_layout = "en-us";
#endif
if(keyboard_layout) {
- kbd_layout = init_keyboard_layout(keyboard_layout);
+ kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
if (!kbd_layout)
exit(1);
}
-
- for (i = 0; i < CURSES_KEYS; i ++)
- keycode2keysym[i] = -1;
-
- for (i = 0; i < CURSES_KEYS; i ++) {
- if (curses2keycode[i] == -1)
- continue;
-
- keycode = curses2keycode[i] & KEY_MASK;
- if (keycode2keysym[keycode] >= 0)
- continue;
-
- for (keysym = 0; keysym < CURSES_KEYS; keysym ++)
- if (curses2keycode[keysym] == keycode) {
- keycode2keysym[keycode] = keysym;
- break;
- }
-
- if (keysym >= CURSES_KEYS)
- keycode2keysym[keycode] = i;
- }
}
void curses_display_init(DisplayState *ds, int full_screen)
{
+ DisplayChangeListener *dcl;
#ifndef _WIN32
if (!isatty(1)) {
fprintf(stderr, "We need a terminal output\n");
atexit(curses_atexit);
#ifndef _WIN32
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
-#ifdef SIGWINCH
+#if defined(SIGWINCH) && defined(KEY_RESIZE)
/* some curses implementations provide a handler, but we
* want to be sure this is handled regardless of the library */
signal(SIGWINCH, curses_winch_handler);
#endif
#endif
- ds->data = (void *) screen;
- ds->linesize = 0;
- ds->depth = 0;
- ds->width = 640;
- ds->height = 400;
- ds->dpy_update = curses_update;
- ds->dpy_resize = curses_resize;
- ds->dpy_refresh = curses_refresh;
- ds->dpy_text_cursor = curses_cursor_position;
+ dcl = (DisplayChangeListener *) qemu_mallocz(sizeof(DisplayChangeListener));
+ dcl->dpy_update = curses_update;
+ dcl->dpy_resize = curses_resize;
+ dcl->dpy_refresh = curses_refresh;
+ dcl->dpy_text_cursor = curses_cursor_position;
+ register_displaychangelistener(ds, dcl);
+ qemu_free_displaysurface(ds);
+ ds->surface = qemu_create_displaysurface_from(640, 400, 0, 0, (uint8_t*) screen);
invalidate = 1;
-
- /* Standard VGA initial text mode dimensions */
- curses_resize(ds, 80, 25);
}