18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * QEMU curses/ncurses display driver 3c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner * 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 2005 Andrzej Zaborowski <balrog@zabor.org> 5c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner * 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Permission is hereby granted, free of charge, to any person obtaining a copy 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * of this software and associated documentation files (the "Software"), to deal 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * in the Software without restriction, including without limitation the rights 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * copies of the Software, and to permit persons to whom the Software is 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * furnished to do so, subject to the following conditions: 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The above copyright notice and this permission notice shall be included in 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * all copies or substantial portions of the Software. 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * THE SOFTWARE. 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <curses.h> 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef _WIN32 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <signal.h> 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/ioctl.h> 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <termios.h> 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef __OpenBSD__ 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define resize_term resizeterm 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-common.h" 371c31e3e43ce4cca85a707dfff631e5e102fdecedDavid 'Digit' Turner#include "ui/console.h" 3834c48ff1e3ad5cd2084ca40188754d45f423750bDavid 'Digit' Turner#include "sysemu/sysemu.h" 395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define FONT_HEIGHT 16 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define FONT_WIDTH 8 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic console_ch_t screen[160 * 100]; 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic WINDOW *screenpad = NULL; 458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int width, height, gwidth, gheight, invalidate; 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int px, py, sminx, sminy, smaxx, smaxy; 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void curses_update(DisplayState *ds, int x, int y, int w, int h) 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project chtype *line; 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project line = ((chtype *) screen) + y * width; 538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (h += y; y < h; y ++, line += width) 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project mvwaddchnstr(screenpad, y, 0, line, width); 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project pnoutrefresh(screenpad, py, px, sminy, sminx, smaxy - 1, smaxx - 1); 578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project refresh(); 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void curses_calc_pad(void) 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (is_fixedsize_console()) { 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project width = gwidth; 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project height = gheight; 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project width = COLS; 678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project height = LINES; 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (screenpad) 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project delwin(screenpad); 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project clear(); 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project refresh(); 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project screenpad = newpad(height, width); 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (width > COLS) { 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project px = (width - COLS) / 2; 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sminx = 0; 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project smaxx = COLS; 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project px = 0; 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sminx = (COLS - width) / 2; 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project smaxx = sminx + width; 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (height > LINES) { 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project py = (height - LINES) / 2; 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sminy = 0; 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project smaxy = LINES; 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project py = 0; 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sminy = (LINES - height) / 2; 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project smaxy = sminy + height; 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void curses_resize(DisplayState *ds) 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (ds_get_width(ds) == gwidth && ds_get_height(ds) == gheight) 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner gwidth = ds_get_width(ds); 1055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner gheight = ds_get_height(ds); 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project curses_calc_pad(); 1085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ds->surface->width = width * FONT_WIDTH; 1095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ds->surface->height = height * FONT_HEIGHT; 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef _WIN32 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(SIGWINCH) && defined(KEY_RESIZE) 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void curses_winch_handler(int signum) 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct winsize { 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned short ws_row; 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned short ws_col; 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned short ws_xpixel; /* unused */ 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned short ws_ypixel; /* unused */ 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } ws; 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* terminal size changed */ 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ioctl(1, TIOCGWINSZ, &ws) == -1) 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project resize_term(ws.ws_row, ws.ws_col); 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project curses_calc_pad(); 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project invalidate = 1; 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* some systems require this */ 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project signal(SIGWINCH, curses_winch_handler); 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void curses_cursor_position(DisplayState *ds, int x, int y) 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (x >= 0) { 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project x = sminx + x - px; 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project y = sminy + y - py; 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (x >= 0 && y >= 0 && x < COLS && y < LINES) { 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project move(y, x); 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project curs_set(1); 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* it seems that curs_set(1) must always be called before 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * curs_set(2) for the latter to have effect */ 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!is_graphic_console()) 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project curs_set(2); 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return; 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project curs_set(0); 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* generic keyboard conversion */ 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "curses_keys.h" 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1619251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turnerstatic kbd_layout_t *kbd_layout = NULL; 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int keycode2keysym[CURSES_KEYS]; 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void curses_refresh(DisplayState *ds) 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int chr, nextchr, keysym, keycode; 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (invalidate) { 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project clear(); 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project refresh(); 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project curses_calc_pad(); 1725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ds->surface->width = FONT_WIDTH * width; 1735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ds->surface->height = FONT_HEIGHT * height; 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project vga_hw_invalidate(); 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project invalidate = 0; 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project vga_hw_text_update(screen); 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nextchr = ERR; 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (1) { 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* while there are any pending key strokes to process */ 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (nextchr == ERR) 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project chr = getch(); 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project chr = nextchr; 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nextchr = ERR; 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (chr == ERR) 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef KEY_RESIZE 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* this shouldn't occur when we use a custom SIGWINCH handler */ 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (chr == KEY_RESIZE) { 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project clear(); 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project refresh(); 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project curses_calc_pad(); 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project curses_update(ds, 0, 0, width, height); 2005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ds->surface->width = FONT_WIDTH * width; 2015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ds->surface->height = FONT_HEIGHT * height; 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project keycode = curses2keycode[chr]; 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (keycode == -1) 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* alt key */ 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (keycode == 1) { 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nextchr = getch(); 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (nextchr != ERR) { 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project keycode = curses2keycode[nextchr]; 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nextchr = ERR; 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (keycode == -1) 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project keycode |= ALT; 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* process keys reserved for qemu */ 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (keycode >= QEMU_KEY_CONSOLE0 && 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project keycode < QEMU_KEY_CONSOLE0 + 9) { 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project erase(); 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project wnoutrefresh(stdscr); 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project console_select(keycode - QEMU_KEY_CONSOLE0); 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project invalidate = 1; 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (kbd_layout && !(keycode & GREY)) { 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project keysym = keycode2keysym[keycode & KEY_MASK]; 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (keysym == -1) 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project keysym = chr; 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project keycode &= ~KEY_MASK; 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project keycode |= keysym2scancode(kbd_layout, keysym); 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (is_graphic_console()) { 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* since terminals don't know about key press and release 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * events, we need to emit both for each key received */ 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (keycode & SHIFT) 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project kbd_put_keycode(SHIFT_CODE); 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (keycode & CNTRL) 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project kbd_put_keycode(CNTRL_CODE); 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (keycode & ALT) 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project kbd_put_keycode(ALT_CODE); 2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (keycode & GREY) 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project kbd_put_keycode(GREY_CODE); 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project kbd_put_keycode(keycode & KEY_MASK); 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (keycode & GREY) 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project kbd_put_keycode(GREY_CODE); 2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project kbd_put_keycode((keycode & KEY_MASK) | KEY_RELEASE); 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (keycode & ALT) 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project kbd_put_keycode(ALT_CODE | KEY_RELEASE); 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (keycode & CNTRL) 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project kbd_put_keycode(CNTRL_CODE | KEY_RELEASE); 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (keycode & SHIFT) 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project kbd_put_keycode(SHIFT_CODE | KEY_RELEASE); 2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } else { 2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project keysym = curses2keysym[chr]; 2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (keysym == -1) 2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project keysym = chr; 2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project kbd_put_keysym(keysym); 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 275c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turnerstatic void curses_cleanup(void *opaque) 2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project endwin(); 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void curses_atexit(void) 2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project curses_cleanup(NULL); 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void curses_setup(void) 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i, colour_default[8] = { 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE, 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project }; 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* input as raw as possible, let everything be interpreted 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * by the guest system */ 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project initscr(); noecho(); intrflush(stdscr, FALSE); 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project nodelay(stdscr, TRUE); nonl(); keypad(stdscr, TRUE); 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project start_color(); raw(); scrollok(stdscr, FALSE); 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; i < 64; i ++) 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project init_pair(i, colour_default[i & 7], colour_default[i >> 3]); 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void curses_keyboard_setup(void) 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int i, keycode, keysym; 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(__APPLE__) 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* always use generic keymaps */ 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!keyboard_layout) 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project keyboard_layout = "en-us"; 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if(keyboard_layout) { 3125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout); 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!kbd_layout) 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project exit(1); 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; i < CURSES_KEYS; i ++) 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project keycode2keysym[i] = -1; 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (i = 0; i < CURSES_KEYS; i ++) { 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (curses2keycode[i] == -1) 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project keycode = curses2keycode[i] & KEY_MASK; 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (keycode2keysym[keycode] >= 0) 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project continue; 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (keysym = 0; keysym < CURSES_KEYS; keysym ++) 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (curses2keycode[keysym] == keycode) { 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project keycode2keysym[keycode] = keysym; 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (keysym >= CURSES_KEYS) 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project keycode2keysym[keycode] = i; 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid curses_display_init(DisplayState *ds, int full_screen) 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner DisplayChangeListener *dcl; 3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef _WIN32 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!isatty(1)) { 3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fprintf(stderr, "We need a terminal output\n"); 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project exit(1); 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project curses_setup(); 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project curses_keyboard_setup(); 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project atexit(curses_atexit); 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef _WIN32 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(SIGWINCH) && defined(KEY_RESIZE) 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* some curses implementations provide a handler, but we 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * want to be sure this is handled regardless of the library */ 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project signal(SIGWINCH, curses_winch_handler); 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 361aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner dcl = (DisplayChangeListener *) g_malloc0(sizeof(DisplayChangeListener)); 3625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner dcl->dpy_update = curses_update; 3635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner dcl->dpy_resize = curses_resize; 3645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner dcl->dpy_refresh = curses_refresh; 3655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner dcl->dpy_text_cursor = curses_cursor_position; 3665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner register_displaychangelistener(ds, dcl); 3675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner qemu_free_displaysurface(ds); 3685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ds->surface = qemu_create_displaysurface_from(640, 400, 0, 0, (uint8_t*) screen); 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project invalidate = 1; 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 372