]> git.proxmox.com Git - qemu.git/blobdiff - curses.c
virtio-blk: Avoid zeroing every request structure
[qemu.git] / curses.c
index d13a7d7427d75c24e749751f5ee5aa910d6bf4ac..ed3165e45e56efd4b28bb74d4d821a87a422470d 100644 (file)
--- a/curses.c
+++ b/curses.c
  * 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
 
@@ -56,7 +59,7 @@ static void curses_update(DisplayState *ds, int x, int y, int w, int h)
 
 static void curses_calc_pad(void)
 {
-    if (is_graphic_console()) {
+    if (is_fixedsize_console()) {
         width = gwidth;
         height = gheight;
     } else {
@@ -93,19 +96,21 @@ static void curses_calc_pad(void)
     }
 }
 
-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 {
@@ -152,21 +157,19 @@ static void curses_cursor_position(DisplayState *ds, int x, int y)
 /* 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;
     }
@@ -186,55 +189,72 @@ static void curses_refresh(DisplayState *ds)
         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 */
@@ -244,12 +264,20 @@ static void curses_refresh(DisplayState *ds)
                 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)
@@ -257,7 +285,7 @@ static void curses_refresh(DisplayState *ds)
             if (keycode & SHIFT)
                 kbd_put_keycode(SHIFT_CODE | KEY_RELEASE);
         } else {
-            keysym = curses2keysym[chr];
+            keysym = curses2qemu[chr];
             if (keysym == -1)
                 keysym = chr;
 
@@ -266,14 +294,9 @@ static void curses_refresh(DisplayState *ds)
     }
 }
 
-static void curses_cleanup(void *opaque) 
-{
-    endwin();
-}
-
 static void curses_atexit(void)
 {
-    curses_cleanup(NULL);
+    endwin();
 }
 
 static void curses_setup(void)
@@ -295,43 +318,21 @@ 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");
@@ -344,27 +345,21 @@ void curses_display_init(DisplayState *ds, int full_screen)
     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);
 }