summaryrefslogtreecommitdiffstats
path: root/qemu/ui
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/ui')
-rw-r--r--qemu/ui/Makefile.objs53
-rw-r--r--qemu/ui/cocoa.m1450
-rw-r--r--qemu/ui/console-gl.c174
-rw-r--r--qemu/ui/console.c2168
-rw-r--r--qemu/ui/curses.c447
-rw-r--r--qemu/ui/curses_keys.h518
-rw-r--r--qemu/ui/cursor.c212
-rw-r--r--qemu/ui/cursor_hidden.xpm37
-rw-r--r--qemu/ui/cursor_left_ptr.xpm39
-rw-r--r--qemu/ui/egl-context.c35
-rw-r--r--qemu/ui/egl-helpers.c269
-rw-r--r--qemu/ui/gtk-egl.c257
-rw-r--r--qemu/ui/gtk-gl-area.c224
-rw-r--r--qemu/ui/gtk.c2212
-rw-r--r--qemu/ui/input-keymap.c203
-rw-r--r--qemu/ui/input-legacy.c272
-rw-r--r--qemu/ui/input-linux.c507
-rw-r--r--qemu/ui/input.c574
-rw-r--r--qemu/ui/keymaps.c241
-rw-r--r--qemu/ui/keymaps.h77
-rw-r--r--qemu/ui/qemu-pixman.c253
-rw-r--r--qemu/ui/qemu-x509.h9
-rw-r--r--qemu/ui/sdl.c1027
-rw-r--r--qemu/ui/sdl2-2d.c161
-rw-r--r--qemu/ui/sdl2-gl.c248
-rw-r--r--qemu/ui/sdl2-input.c101
-rw-r--r--qemu/ui/sdl2-keymap.h267
-rw-r--r--qemu/ui/sdl2.c837
-rw-r--r--qemu/ui/sdl_keysym.h278
-rw-r--r--qemu/ui/sdl_zoom.c94
-rw-r--r--qemu/ui/sdl_zoom.h25
-rw-r--r--qemu/ui/sdl_zoom_template.h219
-rw-r--r--qemu/ui/shader.c136
-rw-r--r--qemu/ui/shader/texture-blit.frag10
-rw-r--r--qemu/ui/shader/texture-blit.vert10
-rw-r--r--qemu/ui/spice-core.c953
-rw-r--r--qemu/ui/spice-display.c936
-rw-r--r--qemu/ui/spice-input.c246
-rw-r--r--qemu/ui/vgafont.h4611
-rw-r--r--qemu/ui/vnc-auth-sasl.c660
-rw-r--r--qemu/ui/vnc-auth-sasl.h75
-rw-r--r--qemu/ui/vnc-auth-vencrypt.c160
-rw-r--r--qemu/ui/vnc-auth-vencrypt.h33
-rw-r--r--qemu/ui/vnc-enc-hextile-template.h211
-rw-r--r--qemu/ui/vnc-enc-hextile.c84
-rw-r--r--qemu/ui/vnc-enc-tight.c1697
-rw-r--r--qemu/ui/vnc-enc-tight.h183
-rw-r--r--qemu/ui/vnc-enc-zlib.c153
-rw-r--r--qemu/ui/vnc-enc-zrle-template.c263
-rw-r--r--qemu/ui/vnc-enc-zrle.c367
-rw-r--r--qemu/ui/vnc-enc-zrle.h40
-rw-r--r--qemu/ui/vnc-enc-zywrle-template.c171
-rw-r--r--qemu/ui/vnc-enc-zywrle.h659
-rw-r--r--qemu/ui/vnc-jobs.c356
-rw-r--r--qemu/ui/vnc-jobs.h70
-rw-r--r--qemu/ui/vnc-palette.c160
-rw-r--r--qemu/ui/vnc-palette.h67
-rw-r--r--qemu/ui/vnc-ws.c125
-rw-r--r--qemu/ui/vnc-ws.h31
-rw-r--r--qemu/ui/vnc.c3880
-rw-r--r--qemu/ui/vnc.h579
-rw-r--r--qemu/ui/vnc_keysym.h720
-rw-r--r--qemu/ui/x_keymap.c169
-rw-r--r--qemu/ui/x_keymap.h32
64 files changed, 0 insertions, 31335 deletions
diff --git a/qemu/ui/Makefile.objs b/qemu/ui/Makefile.objs
deleted file mode 100644
index dc936f150..000000000
--- a/qemu/ui/Makefile.objs
+++ /dev/null
@@ -1,53 +0,0 @@
-vnc-obj-y += vnc.o
-vnc-obj-y += vnc-enc-zlib.o vnc-enc-hextile.o
-vnc-obj-y += vnc-enc-tight.o vnc-palette.o
-vnc-obj-y += vnc-enc-zrle.o
-vnc-obj-y += vnc-auth-vencrypt.o
-vnc-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o
-vnc-obj-y += vnc-ws.o
-vnc-obj-y += vnc-jobs.o
-
-common-obj-y += keymaps.o console.o cursor.o qemu-pixman.o
-common-obj-y += input.o input-keymap.o input-legacy.o
-common-obj-$(CONFIG_LINUX) += input-linux.o
-common-obj-$(CONFIG_SPICE) += spice-core.o spice-input.o spice-display.o
-common-obj-$(CONFIG_SDL) += sdl.mo x_keymap.o
-common-obj-$(CONFIG_COCOA) += cocoa.o
-common-obj-$(CONFIG_CURSES) += curses.o
-common-obj-$(CONFIG_VNC) += $(vnc-obj-y)
-common-obj-$(CONFIG_GTK) += gtk.o x_keymap.o
-
-ifeq ($(CONFIG_SDLABI),1.2)
-sdl.mo-objs := sdl.o sdl_zoom.o
-endif
-ifeq ($(CONFIG_SDLABI),2.0)
-sdl.mo-objs := sdl2.o sdl2-input.o sdl2-2d.o
-ifeq ($(CONFIG_OPENGL),y)
-sdl.mo-objs += sdl2-gl.o
-endif
-endif
-sdl.mo-cflags := $(SDL_CFLAGS)
-
-ifeq ($(CONFIG_OPENGL),y)
-common-obj-y += shader.o
-common-obj-y += console-gl.o
-common-obj-y += egl-helpers.o
-common-obj-y += egl-context.o
-ifeq ($(CONFIG_GTK_GL),y)
-common-obj-$(CONFIG_GTK) += gtk-gl-area.o
-else
-common-obj-$(CONFIG_GTK) += gtk-egl.o
-endif
-endif
-
-gtk.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS)
-gtk-egl.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS) $(OPENGL_CFLAGS)
-gtk-gl-area.o-cflags := $(GTK_CFLAGS) $(VTE_CFLAGS) $(OPENGL_CFLAGS)
-shader.o-cflags += $(OPENGL_CFLAGS)
-console-gl.o-cflags += $(OPENGL_CFLAGS)
-egl-helpers.o-cflags += $(OPENGL_CFLAGS)
-
-gtk-egl.o-libs += $(OPENGL_LIBS)
-shader.o-libs += $(OPENGL_LIBS)
-console-gl.o-libs += $(OPENGL_LIBS)
-egl-helpers.o-libs += $(OPENGL_LIBS)
diff --git a/qemu/ui/cocoa.m b/qemu/ui/cocoa.m
deleted file mode 100644
index 60a7c07ec..000000000
--- a/qemu/ui/cocoa.m
+++ /dev/null
@@ -1,1450 +0,0 @@
-/*
- * QEMU Cocoa CG display driver
- *
- * Copyright (c) 2008 Mike Kronenberg
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-
-#import <Cocoa/Cocoa.h>
-#include <crt_externs.h>
-
-#include "qemu-common.h"
-#include "ui/console.h"
-#include "ui/input.h"
-#include "sysemu/sysemu.h"
-#include "qmp-commands.h"
-#include "sysemu/blockdev.h"
-#include <Carbon/Carbon.h>
-
-#ifndef MAC_OS_X_VERSION_10_5
-#define MAC_OS_X_VERSION_10_5 1050
-#endif
-#ifndef MAC_OS_X_VERSION_10_6
-#define MAC_OS_X_VERSION_10_6 1060
-#endif
-#ifndef MAC_OS_X_VERSION_10_10
-#define MAC_OS_X_VERSION_10_10 101000
-#endif
-
-
-//#define DEBUG
-
-#ifdef DEBUG
-#define COCOA_DEBUG(...) { (void) fprintf (stdout, __VA_ARGS__); }
-#else
-#define COCOA_DEBUG(...) ((void) 0)
-#endif
-
-#define cgrect(nsrect) (*(CGRect *)&(nsrect))
-
-typedef struct {
- int width;
- int height;
- int bitsPerComponent;
- int bitsPerPixel;
-} QEMUScreen;
-
-NSWindow *normalWindow;
-static DisplayChangeListener *dcl;
-static int last_buttons;
-
-int gArgc;
-char **gArgv;
-bool stretch_video;
-NSTextField *pauseLabel;
-NSArray * supportedImageFileTypes;
-
-// Mac to QKeyCode conversion
-const int mac_to_qkeycode_map[] = {
- [kVK_ANSI_A] = Q_KEY_CODE_A,
- [kVK_ANSI_B] = Q_KEY_CODE_B,
- [kVK_ANSI_C] = Q_KEY_CODE_C,
- [kVK_ANSI_D] = Q_KEY_CODE_D,
- [kVK_ANSI_E] = Q_KEY_CODE_E,
- [kVK_ANSI_F] = Q_KEY_CODE_F,
- [kVK_ANSI_G] = Q_KEY_CODE_G,
- [kVK_ANSI_H] = Q_KEY_CODE_H,
- [kVK_ANSI_I] = Q_KEY_CODE_I,
- [kVK_ANSI_J] = Q_KEY_CODE_J,
- [kVK_ANSI_K] = Q_KEY_CODE_K,
- [kVK_ANSI_L] = Q_KEY_CODE_L,
- [kVK_ANSI_M] = Q_KEY_CODE_M,
- [kVK_ANSI_N] = Q_KEY_CODE_N,
- [kVK_ANSI_O] = Q_KEY_CODE_O,
- [kVK_ANSI_P] = Q_KEY_CODE_P,
- [kVK_ANSI_Q] = Q_KEY_CODE_Q,
- [kVK_ANSI_R] = Q_KEY_CODE_R,
- [kVK_ANSI_S] = Q_KEY_CODE_S,
- [kVK_ANSI_T] = Q_KEY_CODE_T,
- [kVK_ANSI_U] = Q_KEY_CODE_U,
- [kVK_ANSI_V] = Q_KEY_CODE_V,
- [kVK_ANSI_W] = Q_KEY_CODE_W,
- [kVK_ANSI_X] = Q_KEY_CODE_X,
- [kVK_ANSI_Y] = Q_KEY_CODE_Y,
- [kVK_ANSI_Z] = Q_KEY_CODE_Z,
-
- [kVK_ANSI_0] = Q_KEY_CODE_0,
- [kVK_ANSI_1] = Q_KEY_CODE_1,
- [kVK_ANSI_2] = Q_KEY_CODE_2,
- [kVK_ANSI_3] = Q_KEY_CODE_3,
- [kVK_ANSI_4] = Q_KEY_CODE_4,
- [kVK_ANSI_5] = Q_KEY_CODE_5,
- [kVK_ANSI_6] = Q_KEY_CODE_6,
- [kVK_ANSI_7] = Q_KEY_CODE_7,
- [kVK_ANSI_8] = Q_KEY_CODE_8,
- [kVK_ANSI_9] = Q_KEY_CODE_9,
-
- [kVK_ANSI_Grave] = Q_KEY_CODE_GRAVE_ACCENT,
- [kVK_ANSI_Minus] = Q_KEY_CODE_MINUS,
- [kVK_ANSI_Equal] = Q_KEY_CODE_EQUAL,
- [kVK_Delete] = Q_KEY_CODE_BACKSPACE,
- [kVK_CapsLock] = Q_KEY_CODE_CAPS_LOCK,
- [kVK_Tab] = Q_KEY_CODE_TAB,
- [kVK_Return] = Q_KEY_CODE_RET,
- [kVK_ANSI_LeftBracket] = Q_KEY_CODE_BRACKET_LEFT,
- [kVK_ANSI_RightBracket] = Q_KEY_CODE_BRACKET_RIGHT,
- [kVK_ANSI_Backslash] = Q_KEY_CODE_BACKSLASH,
- [kVK_ANSI_Semicolon] = Q_KEY_CODE_SEMICOLON,
- [kVK_ANSI_Quote] = Q_KEY_CODE_APOSTROPHE,
- [kVK_ANSI_Comma] = Q_KEY_CODE_COMMA,
- [kVK_ANSI_Period] = Q_KEY_CODE_DOT,
- [kVK_ANSI_Slash] = Q_KEY_CODE_SLASH,
- [kVK_Shift] = Q_KEY_CODE_SHIFT,
- [kVK_RightShift] = Q_KEY_CODE_SHIFT_R,
- [kVK_Control] = Q_KEY_CODE_CTRL,
- [kVK_RightControl] = Q_KEY_CODE_CTRL_R,
- [kVK_Option] = Q_KEY_CODE_ALT,
- [kVK_RightOption] = Q_KEY_CODE_ALT_R,
- [kVK_Command] = Q_KEY_CODE_META_L,
- [0x36] = Q_KEY_CODE_META_R, /* There is no kVK_RightCommand */
- [kVK_Space] = Q_KEY_CODE_SPC,
-
- [kVK_ANSI_Keypad0] = Q_KEY_CODE_KP_0,
- [kVK_ANSI_Keypad1] = Q_KEY_CODE_KP_1,
- [kVK_ANSI_Keypad2] = Q_KEY_CODE_KP_2,
- [kVK_ANSI_Keypad3] = Q_KEY_CODE_KP_3,
- [kVK_ANSI_Keypad4] = Q_KEY_CODE_KP_4,
- [kVK_ANSI_Keypad5] = Q_KEY_CODE_KP_5,
- [kVK_ANSI_Keypad6] = Q_KEY_CODE_KP_6,
- [kVK_ANSI_Keypad7] = Q_KEY_CODE_KP_7,
- [kVK_ANSI_Keypad8] = Q_KEY_CODE_KP_8,
- [kVK_ANSI_Keypad9] = Q_KEY_CODE_KP_9,
- [kVK_ANSI_KeypadDecimal] = Q_KEY_CODE_KP_DECIMAL,
- [kVK_ANSI_KeypadEnter] = Q_KEY_CODE_KP_ENTER,
- [kVK_ANSI_KeypadPlus] = Q_KEY_CODE_KP_ADD,
- [kVK_ANSI_KeypadMinus] = Q_KEY_CODE_KP_SUBTRACT,
- [kVK_ANSI_KeypadMultiply] = Q_KEY_CODE_KP_MULTIPLY,
- [kVK_ANSI_KeypadDivide] = Q_KEY_CODE_KP_DIVIDE,
- [kVK_ANSI_KeypadEquals] = Q_KEY_CODE_KP_EQUALS,
- [kVK_ANSI_KeypadClear] = Q_KEY_CODE_NUM_LOCK,
-
- [kVK_UpArrow] = Q_KEY_CODE_UP,
- [kVK_DownArrow] = Q_KEY_CODE_DOWN,
- [kVK_LeftArrow] = Q_KEY_CODE_LEFT,
- [kVK_RightArrow] = Q_KEY_CODE_RIGHT,
-
- [kVK_Help] = Q_KEY_CODE_INSERT,
- [kVK_Home] = Q_KEY_CODE_HOME,
- [kVK_PageUp] = Q_KEY_CODE_PGUP,
- [kVK_PageDown] = Q_KEY_CODE_PGDN,
- [kVK_End] = Q_KEY_CODE_END,
- [kVK_ForwardDelete] = Q_KEY_CODE_DELETE,
-
- [kVK_Escape] = Q_KEY_CODE_ESC,
-
- /* The Power key can't be used directly because the operating system uses
- * it. This key can be emulated by using it in place of another key such as
- * F1. Don't forget to disable the real key binding.
- */
- /* [kVK_F1] = Q_KEY_CODE_POWER, */
-
- [kVK_F1] = Q_KEY_CODE_F1,
- [kVK_F2] = Q_KEY_CODE_F2,
- [kVK_F3] = Q_KEY_CODE_F3,
- [kVK_F4] = Q_KEY_CODE_F4,
- [kVK_F5] = Q_KEY_CODE_F5,
- [kVK_F6] = Q_KEY_CODE_F6,
- [kVK_F7] = Q_KEY_CODE_F7,
- [kVK_F8] = Q_KEY_CODE_F8,
- [kVK_F9] = Q_KEY_CODE_F9,
- [kVK_F10] = Q_KEY_CODE_F10,
- [kVK_F11] = Q_KEY_CODE_F11,
- [kVK_F12] = Q_KEY_CODE_F12,
- [kVK_F13] = Q_KEY_CODE_PRINT,
- [kVK_F14] = Q_KEY_CODE_SCROLL_LOCK,
- [kVK_F15] = Q_KEY_CODE_PAUSE,
-
- /*
- * The eject and volume keys can't be used here because they are handled at
- * a lower level than what an Application can see.
- */
-};
-
-static int cocoa_keycode_to_qemu(int keycode)
-{
- if (ARRAY_SIZE(mac_to_qkeycode_map) <= keycode) {
- fprintf(stderr, "(cocoa) warning unknown keycode 0x%x\n", keycode);
- return 0;
- }
- return mac_to_qkeycode_map[keycode];
-}
-
-/* Displays an alert dialog box with the specified message */
-static void QEMU_Alert(NSString *message)
-{
- NSAlert *alert;
- alert = [NSAlert new];
- [alert setMessageText: message];
- [alert runModal];
-}
-
-/* Handles any errors that happen with a device transaction */
-static void handleAnyDeviceErrors(Error * err)
-{
- if (err) {
- QEMU_Alert([NSString stringWithCString: error_get_pretty(err)
- encoding: NSASCIIStringEncoding]);
- error_free(err);
- }
-}
-
-/*
- ------------------------------------------------------
- QemuCocoaView
- ------------------------------------------------------
-*/
-@interface QemuCocoaView : NSView
-{
- QEMUScreen screen;
- NSWindow *fullScreenWindow;
- float cx,cy,cw,ch,cdx,cdy;
- CGDataProviderRef dataProviderRef;
- int modifiers_state[256];
- BOOL isMouseGrabbed;
- BOOL isFullscreen;
- BOOL isAbsoluteEnabled;
- BOOL isMouseDeassociated;
-}
-- (void) switchSurface:(DisplaySurface *)surface;
-- (void) grabMouse;
-- (void) ungrabMouse;
-- (void) toggleFullScreen:(id)sender;
-- (void) handleEvent:(NSEvent *)event;
-- (void) setAbsoluteEnabled:(BOOL)tIsAbsoluteEnabled;
-/* The state surrounding mouse grabbing is potentially confusing.
- * isAbsoluteEnabled tracks qemu_input_is_absolute() [ie "is the emulated
- * pointing device an absolute-position one?"], but is only updated on
- * next refresh.
- * isMouseGrabbed tracks whether GUI events are directed to the guest;
- * it controls whether special keys like Cmd get sent to the guest,
- * and whether we capture the mouse when in non-absolute mode.
- * isMouseDeassociated tracks whether we've told MacOSX to disassociate
- * the mouse and mouse cursor position by calling
- * CGAssociateMouseAndMouseCursorPosition(FALSE)
- * (which basically happens if we grab in non-absolute mode).
- */
-- (BOOL) isMouseGrabbed;
-- (BOOL) isAbsoluteEnabled;
-- (BOOL) isMouseDeassociated;
-- (float) cdx;
-- (float) cdy;
-- (QEMUScreen) gscreen;
-- (void) raiseAllKeys;
-@end
-
-QemuCocoaView *cocoaView;
-
-@implementation QemuCocoaView
-- (id)initWithFrame:(NSRect)frameRect
-{
- COCOA_DEBUG("QemuCocoaView: initWithFrame\n");
-
- self = [super initWithFrame:frameRect];
- if (self) {
-
- screen.bitsPerComponent = 8;
- screen.bitsPerPixel = 32;
- screen.width = frameRect.size.width;
- screen.height = frameRect.size.height;
-
- }
- return self;
-}
-
-- (void) dealloc
-{
- COCOA_DEBUG("QemuCocoaView: dealloc\n");
-
- if (dataProviderRef)
- CGDataProviderRelease(dataProviderRef);
-
- [super dealloc];
-}
-
-- (BOOL) isOpaque
-{
- return YES;
-}
-
-- (BOOL) screenContainsPoint:(NSPoint) p
-{
- return (p.x > -1 && p.x < screen.width && p.y > -1 && p.y < screen.height);
-}
-
-- (void) hideCursor
-{
- if (!cursor_hide) {
- return;
- }
- [NSCursor hide];
-}
-
-- (void) unhideCursor
-{
- if (!cursor_hide) {
- return;
- }
- [NSCursor unhide];
-}
-
-- (void) drawRect:(NSRect) rect
-{
- COCOA_DEBUG("QemuCocoaView: drawRect\n");
-
- // get CoreGraphic context
- CGContextRef viewContextRef = [[NSGraphicsContext currentContext] graphicsPort];
- CGContextSetInterpolationQuality (viewContextRef, kCGInterpolationNone);
- CGContextSetShouldAntialias (viewContextRef, NO);
-
- // draw screen bitmap directly to Core Graphics context
- if (!dataProviderRef) {
- // Draw request before any guest device has set up a framebuffer:
- // just draw an opaque black rectangle
- CGContextSetRGBFillColor(viewContextRef, 0, 0, 0, 1.0);
- CGContextFillRect(viewContextRef, NSRectToCGRect(rect));
- } else {
- CGImageRef imageRef = CGImageCreate(
- screen.width, //width
- screen.height, //height
- screen.bitsPerComponent, //bitsPerComponent
- screen.bitsPerPixel, //bitsPerPixel
- (screen.width * (screen.bitsPerComponent/2)), //bytesPerRow
-#ifdef __LITTLE_ENDIAN__
- CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB), //colorspace for OS X >= 10.4
- kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst,
-#else
- CGColorSpaceCreateDeviceRGB(), //colorspace for OS X < 10.4 (actually ppc)
- kCGImageAlphaNoneSkipFirst, //bitmapInfo
-#endif
- dataProviderRef, //provider
- NULL, //decode
- 0, //interpolate
- kCGRenderingIntentDefault //intent
- );
- // selective drawing code (draws only dirty rectangles) (OS X >= 10.4)
- const NSRect *rectList;
- NSInteger rectCount;
- int i;
- CGImageRef clipImageRef;
- CGRect clipRect;
-
- [self getRectsBeingDrawn:&rectList count:&rectCount];
- for (i = 0; i < rectCount; i++) {
- clipRect.origin.x = rectList[i].origin.x / cdx;
- clipRect.origin.y = (float)screen.height - (rectList[i].origin.y + rectList[i].size.height) / cdy;
- clipRect.size.width = rectList[i].size.width / cdx;
- clipRect.size.height = rectList[i].size.height / cdy;
- clipImageRef = CGImageCreateWithImageInRect(
- imageRef,
- clipRect
- );
- CGContextDrawImage (viewContextRef, cgrect(rectList[i]), clipImageRef);
- CGImageRelease (clipImageRef);
- }
- CGImageRelease (imageRef);
- }
-}
-
-- (void) setContentDimensions
-{
- COCOA_DEBUG("QemuCocoaView: setContentDimensions\n");
-
- if (isFullscreen) {
- cdx = [[NSScreen mainScreen] frame].size.width / (float)screen.width;
- cdy = [[NSScreen mainScreen] frame].size.height / (float)screen.height;
-
- /* stretches video, but keeps same aspect ratio */
- if (stretch_video == true) {
- /* use smallest stretch value - prevents clipping on sides */
- if (MIN(cdx, cdy) == cdx) {
- cdy = cdx;
- } else {
- cdx = cdy;
- }
- } else { /* No stretching */
- cdx = cdy = 1;
- }
- cw = screen.width * cdx;
- ch = screen.height * cdy;
- cx = ([[NSScreen mainScreen] frame].size.width - cw) / 2.0;
- cy = ([[NSScreen mainScreen] frame].size.height - ch) / 2.0;
- } else {
- cx = 0;
- cy = 0;
- cw = screen.width;
- ch = screen.height;
- cdx = 1.0;
- cdy = 1.0;
- }
-}
-
-- (void) switchSurface:(DisplaySurface *)surface
-{
- COCOA_DEBUG("QemuCocoaView: switchSurface\n");
-
- int w = surface_width(surface);
- int h = surface_height(surface);
- /* cdx == 0 means this is our very first surface, in which case we need
- * to recalculate the content dimensions even if it happens to be the size
- * of the initial empty window.
- */
- bool isResize = (w != screen.width || h != screen.height || cdx == 0.0);
-
- int oldh = screen.height;
- if (isResize) {
- // Resize before we trigger the redraw, or we'll redraw at the wrong size
- COCOA_DEBUG("switchSurface: new size %d x %d\n", w, h);
- screen.width = w;
- screen.height = h;
- [self setContentDimensions];
- [self setFrame:NSMakeRect(cx, cy, cw, ch)];
- }
-
- // update screenBuffer
- if (dataProviderRef)
- CGDataProviderRelease(dataProviderRef);
-
- //sync host window color space with guests
- screen.bitsPerPixel = surface_bits_per_pixel(surface);
- screen.bitsPerComponent = surface_bytes_per_pixel(surface) * 2;
-
- dataProviderRef = CGDataProviderCreateWithData(NULL, surface_data(surface), w * 4 * h, NULL);
-
- // update windows
- if (isFullscreen) {
- [[fullScreenWindow contentView] setFrame:[[NSScreen mainScreen] frame]];
- [normalWindow setFrame:NSMakeRect([normalWindow frame].origin.x, [normalWindow frame].origin.y - h + oldh, w, h + [normalWindow frame].size.height - oldh) display:NO animate:NO];
- } else {
- if (qemu_name)
- [normalWindow setTitle:[NSString stringWithFormat:@"QEMU %s", qemu_name]];
- [normalWindow setFrame:NSMakeRect([normalWindow frame].origin.x, [normalWindow frame].origin.y - h + oldh, w, h + [normalWindow frame].size.height - oldh) display:YES animate:NO];
- }
-
- if (isResize) {
- [normalWindow center];
- }
-}
-
-- (void) toggleFullScreen:(id)sender
-{
- COCOA_DEBUG("QemuCocoaView: toggleFullScreen\n");
-
- if (isFullscreen) { // switch from fullscreen to desktop
- isFullscreen = FALSE;
- [self ungrabMouse];
- [self setContentDimensions];
- if ([NSView respondsToSelector:@selector(exitFullScreenModeWithOptions:)]) { // test if "exitFullScreenModeWithOptions" is supported on host at runtime
- [self exitFullScreenModeWithOptions:nil];
- } else {
- [fullScreenWindow close];
- [normalWindow setContentView: self];
- [normalWindow makeKeyAndOrderFront: self];
- [NSMenu setMenuBarVisible:YES];
- }
- } else { // switch from desktop to fullscreen
- isFullscreen = TRUE;
- [normalWindow orderOut: nil]; /* Hide the window */
- [self grabMouse];
- [self setContentDimensions];
- if ([NSView respondsToSelector:@selector(enterFullScreenMode:withOptions:)]) { // test if "enterFullScreenMode:withOptions" is supported on host at runtime
- [self enterFullScreenMode:[NSScreen mainScreen] withOptions:[NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithBool:NO], NSFullScreenModeAllScreens,
- [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO], kCGDisplayModeIsStretched, nil], NSFullScreenModeSetting,
- nil]];
- } else {
- [NSMenu setMenuBarVisible:NO];
- fullScreenWindow = [[NSWindow alloc] initWithContentRect:[[NSScreen mainScreen] frame]
- styleMask:NSBorderlessWindowMask
- backing:NSBackingStoreBuffered
- defer:NO];
- [fullScreenWindow setAcceptsMouseMovedEvents: YES];
- [fullScreenWindow setHasShadow:NO];
- [fullScreenWindow setBackgroundColor: [NSColor blackColor]];
- [self setFrame:NSMakeRect(cx, cy, cw, ch)];
- [[fullScreenWindow contentView] addSubview: self];
- [fullScreenWindow makeKeyAndOrderFront:self];
- }
- }
-}
-
-- (void) handleEvent:(NSEvent *)event
-{
- COCOA_DEBUG("QemuCocoaView: handleEvent\n");
-
- int buttons = 0;
- int keycode;
- bool mouse_event = false;
- NSPoint p = [event locationInWindow];
-
- switch ([event type]) {
- case NSFlagsChanged:
- keycode = cocoa_keycode_to_qemu([event keyCode]);
-
- if ((keycode == Q_KEY_CODE_META_L || keycode == Q_KEY_CODE_META_R)
- && !isMouseGrabbed) {
- /* Don't pass command key changes to guest unless mouse is grabbed */
- keycode = 0;
- }
-
- if (keycode) {
- // emulate caps lock and num lock keydown and keyup
- if (keycode == Q_KEY_CODE_CAPS_LOCK ||
- keycode == Q_KEY_CODE_NUM_LOCK) {
- qemu_input_event_send_key_qcode(dcl->con, keycode, true);
- qemu_input_event_send_key_qcode(dcl->con, keycode, false);
- } else if (qemu_console_is_graphic(NULL)) {
- if (modifiers_state[keycode] == 0) { // keydown
- qemu_input_event_send_key_qcode(dcl->con, keycode, true);
- modifiers_state[keycode] = 1;
- } else { // keyup
- qemu_input_event_send_key_qcode(dcl->con, keycode, false);
- modifiers_state[keycode] = 0;
- }
- }
- }
-
- // release Mouse grab when pressing ctrl+alt
- if (([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask)) {
- [self ungrabMouse];
- }
- break;
- case NSKeyDown:
- keycode = cocoa_keycode_to_qemu([event keyCode]);
-
- // forward command key combos to the host UI unless the mouse is grabbed
- if (!isMouseGrabbed && ([event modifierFlags] & NSCommandKeyMask)) {
- [NSApp sendEvent:event];
- return;
- }
-
- // default
-
- // handle control + alt Key Combos (ctrl+alt is reserved for QEMU)
- if (([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask)) {
- switch (keycode) {
-
- // enable graphic console
- case Q_KEY_CODE_1 ... Q_KEY_CODE_9: // '1' to '9' keys
- console_select(keycode - 11);
- break;
- }
-
- // handle keys for graphic console
- } else if (qemu_console_is_graphic(NULL)) {
- qemu_input_event_send_key_qcode(dcl->con, keycode, true);
-
- // handlekeys for Monitor
- } else {
- int keysym = 0;
- switch([event keyCode]) {
- case 115:
- keysym = QEMU_KEY_HOME;
- break;
- case 117:
- keysym = QEMU_KEY_DELETE;
- break;
- case 119:
- keysym = QEMU_KEY_END;
- break;
- case 123:
- keysym = QEMU_KEY_LEFT;
- break;
- case 124:
- keysym = QEMU_KEY_RIGHT;
- break;
- case 125:
- keysym = QEMU_KEY_DOWN;
- break;
- case 126:
- keysym = QEMU_KEY_UP;
- break;
- default:
- {
- NSString *ks = [event characters];
- if ([ks length] > 0)
- keysym = [ks characterAtIndex:0];
- }
- }
- if (keysym)
- kbd_put_keysym(keysym);
- }
- break;
- case NSKeyUp:
- keycode = cocoa_keycode_to_qemu([event keyCode]);
-
- // don't pass the guest a spurious key-up if we treated this
- // command-key combo as a host UI action
- if (!isMouseGrabbed && ([event modifierFlags] & NSCommandKeyMask)) {
- return;
- }
-
- if (qemu_console_is_graphic(NULL)) {
- qemu_input_event_send_key_qcode(dcl->con, keycode, false);
- }
- break;
- case NSMouseMoved:
- if (isAbsoluteEnabled) {
- if (![self screenContainsPoint:p] || ![[self window] isKeyWindow]) {
- if (isMouseGrabbed) {
- [self ungrabMouse];
- }
- } else {
- if (!isMouseGrabbed) {
- [self grabMouse];
- }
- }
- }
- mouse_event = true;
- break;
- case NSLeftMouseDown:
- if ([event modifierFlags] & NSCommandKeyMask) {
- buttons |= MOUSE_EVENT_RBUTTON;
- } else {
- buttons |= MOUSE_EVENT_LBUTTON;
- }
- mouse_event = true;
- break;
- case NSRightMouseDown:
- buttons |= MOUSE_EVENT_RBUTTON;
- mouse_event = true;
- break;
- case NSOtherMouseDown:
- buttons |= MOUSE_EVENT_MBUTTON;
- mouse_event = true;
- break;
- case NSLeftMouseDragged:
- if ([event modifierFlags] & NSCommandKeyMask) {
- buttons |= MOUSE_EVENT_RBUTTON;
- } else {
- buttons |= MOUSE_EVENT_LBUTTON;
- }
- mouse_event = true;
- break;
- case NSRightMouseDragged:
- buttons |= MOUSE_EVENT_RBUTTON;
- mouse_event = true;
- break;
- case NSOtherMouseDragged:
- buttons |= MOUSE_EVENT_MBUTTON;
- mouse_event = true;
- break;
- case NSLeftMouseUp:
- mouse_event = true;
- if (!isMouseGrabbed && [self screenContainsPoint:p]) {
- [self grabMouse];
- }
- break;
- case NSRightMouseUp:
- mouse_event = true;
- break;
- case NSOtherMouseUp:
- mouse_event = true;
- break;
- case NSScrollWheel:
- if (isMouseGrabbed) {
- buttons |= ([event deltaY] < 0) ?
- MOUSE_EVENT_WHEELUP : MOUSE_EVENT_WHEELDN;
- }
- mouse_event = true;
- break;
- default:
- [NSApp sendEvent:event];
- }
-
- if (mouse_event) {
- /* Don't send button events to the guest unless we've got a
- * mouse grab or window focus. If we have neither then this event
- * is the user clicking on the background window to activate and
- * bring us to the front, which will be done by the sendEvent
- * call below. We definitely don't want to pass that click through
- * to the guest.
- */
- if ((isMouseGrabbed || [[self window] isKeyWindow]) &&
- (last_buttons != buttons)) {
- static uint32_t bmap[INPUT_BUTTON__MAX] = {
- [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON,
- [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
- [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON,
- [INPUT_BUTTON_WHEEL_UP] = MOUSE_EVENT_WHEELUP,
- [INPUT_BUTTON_WHEEL_DOWN] = MOUSE_EVENT_WHEELDN,
- };
- qemu_input_update_buttons(dcl->con, bmap, last_buttons, buttons);
- last_buttons = buttons;
- }
- if (isMouseGrabbed) {
- if (isAbsoluteEnabled) {
- /* Note that the origin for Cocoa mouse coords is bottom left, not top left.
- * The check on screenContainsPoint is to avoid sending out of range values for
- * clicks in the titlebar.
- */
- if ([self screenContainsPoint:p]) {
- qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, p.x, screen.width);
- qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, screen.height - p.y, screen.height);
- }
- } else {
- qemu_input_queue_rel(dcl->con, INPUT_AXIS_X, (int)[event deltaX]);
- qemu_input_queue_rel(dcl->con, INPUT_AXIS_Y, (int)[event deltaY]);
- }
- } else {
- [NSApp sendEvent:event];
- }
- qemu_input_event_sync();
- }
-}
-
-- (void) grabMouse
-{
- COCOA_DEBUG("QemuCocoaView: grabMouse\n");
-
- if (!isFullscreen) {
- if (qemu_name)
- [normalWindow setTitle:[NSString stringWithFormat:@"QEMU %s - (Press ctrl + alt to release Mouse)", qemu_name]];
- else
- [normalWindow setTitle:@"QEMU - (Press ctrl + alt to release Mouse)"];
- }
- [self hideCursor];
- if (!isAbsoluteEnabled) {
- isMouseDeassociated = TRUE;
- CGAssociateMouseAndMouseCursorPosition(FALSE);
- }
- isMouseGrabbed = TRUE; // while isMouseGrabbed = TRUE, QemuCocoaApp sends all events to [cocoaView handleEvent:]
-}
-
-- (void) ungrabMouse
-{
- COCOA_DEBUG("QemuCocoaView: ungrabMouse\n");
-
- if (!isFullscreen) {
- if (qemu_name)
- [normalWindow setTitle:[NSString stringWithFormat:@"QEMU %s", qemu_name]];
- else
- [normalWindow setTitle:@"QEMU"];
- }
- [self unhideCursor];
- if (isMouseDeassociated) {
- CGAssociateMouseAndMouseCursorPosition(TRUE);
- isMouseDeassociated = FALSE;
- }
- isMouseGrabbed = FALSE;
-}
-
-- (void) setAbsoluteEnabled:(BOOL)tIsAbsoluteEnabled {isAbsoluteEnabled = tIsAbsoluteEnabled;}
-- (BOOL) isMouseGrabbed {return isMouseGrabbed;}
-- (BOOL) isAbsoluteEnabled {return isAbsoluteEnabled;}
-- (BOOL) isMouseDeassociated {return isMouseDeassociated;}
-- (float) cdx {return cdx;}
-- (float) cdy {return cdy;}
-- (QEMUScreen) gscreen {return screen;}
-
-/*
- * Makes the target think all down keys are being released.
- * This prevents a stuck key problem, since we will not see
- * key up events for those keys after we have lost focus.
- */
-- (void) raiseAllKeys
-{
- int index;
- const int max_index = ARRAY_SIZE(modifiers_state);
-
- for (index = 0; index < max_index; index++) {
- if (modifiers_state[index]) {
- modifiers_state[index] = 0;
- qemu_input_event_send_key_qcode(dcl->con, index, false);
- }
- }
-}
-@end
-
-
-
-/*
- ------------------------------------------------------
- QemuCocoaAppController
- ------------------------------------------------------
-*/
-@interface QemuCocoaAppController : NSObject
-#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
- <NSWindowDelegate, NSApplicationDelegate>
-#endif
-{
-}
-- (void)startEmulationWithArgc:(int)argc argv:(char**)argv;
-- (void)doToggleFullScreen:(id)sender;
-- (void)toggleFullScreen:(id)sender;
-- (void)showQEMUDoc:(id)sender;
-- (void)showQEMUTec:(id)sender;
-- (void)zoomToFit:(id) sender;
-- (void)displayConsole:(id)sender;
-- (void)pauseQEMU:(id)sender;
-- (void)resumeQEMU:(id)sender;
-- (void)displayPause;
-- (void)removePause;
-- (void)restartQEMU:(id)sender;
-- (void)powerDownQEMU:(id)sender;
-- (void)ejectDeviceMedia:(id)sender;
-- (void)changeDeviceMedia:(id)sender;
-- (BOOL)verifyQuit;
-- (void)openDocumentation:(NSString *)filename;
-@end
-
-@implementation QemuCocoaAppController
-- (id) init
-{
- COCOA_DEBUG("QemuCocoaAppController: init\n");
-
- self = [super init];
- if (self) {
-
- // create a view and add it to the window
- cocoaView = [[QemuCocoaView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 640.0, 480.0)];
- if(!cocoaView) {
- fprintf(stderr, "(cocoa) can't create a view\n");
- exit(1);
- }
-
- // create a window
- normalWindow = [[NSWindow alloc] initWithContentRect:[cocoaView frame]
- styleMask:NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask
- backing:NSBackingStoreBuffered defer:NO];
- if(!normalWindow) {
- fprintf(stderr, "(cocoa) can't create window\n");
- exit(1);
- }
- [normalWindow setAcceptsMouseMovedEvents:YES];
- [normalWindow setTitle:@"QEMU"];
- [normalWindow setContentView:cocoaView];
-#if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_10)
- [normalWindow useOptimizedDrawing:YES];
-#endif
- [normalWindow makeKeyAndOrderFront:self];
- [normalWindow center];
- [normalWindow setDelegate: self];
- stretch_video = false;
-
- /* Used for displaying pause on the screen */
- pauseLabel = [NSTextField new];
- [pauseLabel setBezeled:YES];
- [pauseLabel setDrawsBackground:YES];
- [pauseLabel setBackgroundColor: [NSColor whiteColor]];
- [pauseLabel setEditable:NO];
- [pauseLabel setSelectable:NO];
- [pauseLabel setStringValue: @"Paused"];
- [pauseLabel setFont: [NSFont fontWithName: @"Helvetica" size: 90]];
- [pauseLabel setTextColor: [NSColor blackColor]];
- [pauseLabel sizeToFit];
-
- // set the supported image file types that can be opened
- supportedImageFileTypes = [NSArray arrayWithObjects: @"img", @"iso", @"dmg",
- @"qcow", @"qcow2", @"cloop", @"vmdk", @"cdr",
- nil];
- }
- return self;
-}
-
-- (void) dealloc
-{
- COCOA_DEBUG("QemuCocoaAppController: dealloc\n");
-
- if (cocoaView)
- [cocoaView release];
- [super dealloc];
-}
-
-- (void)applicationDidFinishLaunching: (NSNotification *) note
-{
- COCOA_DEBUG("QemuCocoaAppController: applicationDidFinishLaunching\n");
- // launch QEMU, with the global args
- [self startEmulationWithArgc:gArgc argv:(char **)gArgv];
-}
-
-- (void)applicationWillTerminate:(NSNotification *)aNotification
-{
- COCOA_DEBUG("QemuCocoaAppController: applicationWillTerminate\n");
-
- qemu_system_shutdown_request();
- exit(0);
-}
-
-- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
-{
- return YES;
-}
-
-- (NSApplicationTerminateReply)applicationShouldTerminate:
- (NSApplication *)sender
-{
- COCOA_DEBUG("QemuCocoaAppController: applicationShouldTerminate\n");
- return [self verifyQuit];
-}
-
-/* Called when the user clicks on a window's close button */
-- (BOOL)windowShouldClose:(id)sender
-{
- COCOA_DEBUG("QemuCocoaAppController: windowShouldClose\n");
- [NSApp terminate: sender];
- /* If the user allows the application to quit then the call to
- * NSApp terminate will never return. If we get here then the user
- * cancelled the quit, so we should return NO to not permit the
- * closing of this window.
- */
- return NO;
-}
-
-/* Called when QEMU goes into the background */
-- (void) applicationWillResignActive: (NSNotification *)aNotification
-{
- COCOA_DEBUG("QemuCocoaAppController: applicationWillResignActive\n");
- [cocoaView raiseAllKeys];
-}
-
-- (void)startEmulationWithArgc:(int)argc argv:(char**)argv
-{
- COCOA_DEBUG("QemuCocoaAppController: startEmulationWithArgc\n");
-
- int status;
- status = qemu_main(argc, argv, *_NSGetEnviron());
- exit(status);
-}
-
-/* We abstract the method called by the Enter Fullscreen menu item
- * because Mac OS 10.7 and higher disables it. This is because of the
- * menu item's old selector's name toggleFullScreen:
- */
-- (void) doToggleFullScreen:(id)sender
-{
- [self toggleFullScreen:(id)sender];
-}
-
-- (void)toggleFullScreen:(id)sender
-{
- COCOA_DEBUG("QemuCocoaAppController: toggleFullScreen\n");
-
- [cocoaView toggleFullScreen:sender];
-}
-
-/* Tries to find then open the specified filename */
-- (void) openDocumentation: (NSString *) filename
-{
- /* Where to look for local files */
- NSString *path_array[] = {@"../share/doc/qemu/", @"../doc/qemu/", @"../"};
- NSString *full_file_path;
-
- /* iterate thru the possible paths until the file is found */
- int index;
- for (index = 0; index < ARRAY_SIZE(path_array); index++) {
- full_file_path = [[NSBundle mainBundle] executablePath];
- full_file_path = [full_file_path stringByDeletingLastPathComponent];
- full_file_path = [NSString stringWithFormat: @"%@/%@%@", full_file_path,
- path_array[index], filename];
- if ([[NSWorkspace sharedWorkspace] openFile: full_file_path] == YES) {
- return;
- }
- }
-
- /* If none of the paths opened a file */
- NSBeep();
- QEMU_Alert(@"Failed to open file");
-}
-
-- (void)showQEMUDoc:(id)sender
-{
- COCOA_DEBUG("QemuCocoaAppController: showQEMUDoc\n");
-
- [self openDocumentation: @"qemu-doc.html"];
-}
-
-- (void)showQEMUTec:(id)sender
-{
- COCOA_DEBUG("QemuCocoaAppController: showQEMUTec\n");
-
- [self openDocumentation: @"qemu-tech.html"];
-}
-
-/* Stretches video to fit host monitor size */
-- (void)zoomToFit:(id) sender
-{
- stretch_video = !stretch_video;
- if (stretch_video == true) {
- [sender setState: NSOnState];
- } else {
- [sender setState: NSOffState];
- }
-}
-
-/* Displays the console on the screen */
-- (void)displayConsole:(id)sender
-{
- console_select([sender tag]);
-}
-
-/* Pause the guest */
-- (void)pauseQEMU:(id)sender
-{
- qmp_stop(NULL);
- [sender setEnabled: NO];
- [[[sender menu] itemWithTitle: @"Resume"] setEnabled: YES];
- [self displayPause];
-}
-
-/* Resume running the guest operating system */
-- (void)resumeQEMU:(id) sender
-{
- qmp_cont(NULL);
- [sender setEnabled: NO];
- [[[sender menu] itemWithTitle: @"Pause"] setEnabled: YES];
- [self removePause];
-}
-
-/* Displays the word pause on the screen */
-- (void)displayPause
-{
- /* Coordinates have to be calculated each time because the window can change its size */
- int xCoord, yCoord, width, height;
- xCoord = ([normalWindow frame].size.width - [pauseLabel frame].size.width)/2;
- yCoord = [normalWindow frame].size.height - [pauseLabel frame].size.height - ([pauseLabel frame].size.height * .5);
- width = [pauseLabel frame].size.width;
- height = [pauseLabel frame].size.height;
- [pauseLabel setFrame: NSMakeRect(xCoord, yCoord, width, height)];
- [cocoaView addSubview: pauseLabel];
-}
-
-/* Removes the word pause from the screen */
-- (void)removePause
-{
- [pauseLabel removeFromSuperview];
-}
-
-/* Restarts QEMU */
-- (void)restartQEMU:(id)sender
-{
- qmp_system_reset(NULL);
-}
-
-/* Powers down QEMU */
-- (void)powerDownQEMU:(id)sender
-{
- qmp_system_powerdown(NULL);
-}
-
-/* Ejects the media.
- * Uses sender's tag to figure out the device to eject.
- */
-- (void)ejectDeviceMedia:(id)sender
-{
- NSString * drive;
- drive = [sender representedObject];
- if(drive == nil) {
- NSBeep();
- QEMU_Alert(@"Failed to find drive to eject!");
- return;
- }
-
- Error *err = NULL;
- qmp_eject([drive cStringUsingEncoding: NSASCIIStringEncoding], false, false, &err);
- handleAnyDeviceErrors(err);
-}
-
-/* Displays a dialog box asking the user to select an image file to load.
- * Uses sender's represented object value to figure out which drive to use.
- */
-- (void)changeDeviceMedia:(id)sender
-{
- /* Find the drive name */
- NSString * drive;
- drive = [sender representedObject];
- if(drive == nil) {
- NSBeep();
- QEMU_Alert(@"Could not find drive!");
- return;
- }
-
- /* Display the file open dialog */
- NSOpenPanel * openPanel;
- openPanel = [NSOpenPanel openPanel];
- [openPanel setCanChooseFiles: YES];
- [openPanel setAllowsMultipleSelection: NO];
- [openPanel setAllowedFileTypes: supportedImageFileTypes];
- if([openPanel runModal] == NSFileHandlingPanelOKButton) {
- NSString * file = [[[openPanel URLs] objectAtIndex: 0] path];
- if(file == nil) {
- NSBeep();
- QEMU_Alert(@"Failed to convert URL to file path!");
- return;
- }
-
- Error *err = NULL;
- qmp_blockdev_change_medium([drive cStringUsingEncoding:
- NSASCIIStringEncoding],
- [file cStringUsingEncoding:
- NSASCIIStringEncoding],
- true, "raw",
- false, 0,
- &err);
- handleAnyDeviceErrors(err);
- }
-}
-
-/* Verifies if the user really wants to quit */
-- (BOOL)verifyQuit
-{
- NSAlert *alert = [NSAlert new];
- [alert autorelease];
- [alert setMessageText: @"Are you sure you want to quit QEMU?"];
- [alert addButtonWithTitle: @"Cancel"];
- [alert addButtonWithTitle: @"Quit"];
- if([alert runModal] == NSAlertSecondButtonReturn) {
- return YES;
- } else {
- return NO;
- }
-}
-
-@end
-
-
-int main (int argc, const char * argv[]) {
-
- gArgc = argc;
- gArgv = (char **)argv;
- int i;
-
- /* In case we don't need to display a window, let's not do that */
- for (i = 1; i < argc; i++) {
- const char *opt = argv[i];
-
- if (opt[0] == '-') {
- /* Treat --foo the same as -foo. */
- if (opt[1] == '-') {
- opt++;
- }
- if (!strcmp(opt, "-h") || !strcmp(opt, "-help") ||
- !strcmp(opt, "-vnc") ||
- !strcmp(opt, "-nographic") ||
- !strcmp(opt, "-version") ||
- !strcmp(opt, "-curses") ||
- !strcmp(opt, "-display") ||
- !strcmp(opt, "-qtest")) {
- return qemu_main(gArgc, gArgv, *_NSGetEnviron());
- }
- }
- }
-
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-
- // Pull this console process up to being a fully-fledged graphical
- // app with a menubar and Dock icon
- ProcessSerialNumber psn = { 0, kCurrentProcess };
- TransformProcessType(&psn, kProcessTransformToForegroundApplication);
-
- [NSApplication sharedApplication];
-
- // Add menus
- NSMenu *menu;
- NSMenuItem *menuItem;
-
- [NSApp setMainMenu:[[NSMenu alloc] init]];
-
- // Application menu
- menu = [[NSMenu alloc] initWithTitle:@""];
- [menu addItemWithTitle:@"About QEMU" action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; // About QEMU
- [menu addItem:[NSMenuItem separatorItem]]; //Separator
- [menu addItemWithTitle:@"Hide QEMU" action:@selector(hide:) keyEquivalent:@"h"]; //Hide QEMU
- menuItem = (NSMenuItem *)[menu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; // Hide Others
- [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
- [menu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; // Show All
- [menu addItem:[NSMenuItem separatorItem]]; //Separator
- [menu addItemWithTitle:@"Quit QEMU" action:@selector(terminate:) keyEquivalent:@"q"];
- menuItem = [[NSMenuItem alloc] initWithTitle:@"Apple" action:nil keyEquivalent:@""];
- [menuItem setSubmenu:menu];
- [[NSApp mainMenu] addItem:menuItem];
- [NSApp performSelector:@selector(setAppleMenu:) withObject:menu]; // Workaround (this method is private since 10.4+)
-
- // Machine menu
- menu = [[NSMenu alloc] initWithTitle: @"Machine"];
- [menu setAutoenablesItems: NO];
- [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Pause" action: @selector(pauseQEMU:) keyEquivalent: @""] autorelease]];
- menuItem = [[[NSMenuItem alloc] initWithTitle: @"Resume" action: @selector(resumeQEMU:) keyEquivalent: @""] autorelease];
- [menu addItem: menuItem];
- [menuItem setEnabled: NO];
- [menu addItem: [NSMenuItem separatorItem]];
- [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Reset" action: @selector(restartQEMU:) keyEquivalent: @""] autorelease]];
- [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Power Down" action: @selector(powerDownQEMU:) keyEquivalent: @""] autorelease]];
- menuItem = [[[NSMenuItem alloc] initWithTitle: @"Machine" action:nil keyEquivalent:@""] autorelease];
- [menuItem setSubmenu:menu];
- [[NSApp mainMenu] addItem:menuItem];
-
- // View menu
- menu = [[NSMenu alloc] initWithTitle:@"View"];
- [menu addItem: [[[NSMenuItem alloc] initWithTitle:@"Enter Fullscreen" action:@selector(doToggleFullScreen:) keyEquivalent:@"f"] autorelease]]; // Fullscreen
- [menu addItem: [[[NSMenuItem alloc] initWithTitle:@"Zoom To Fit" action:@selector(zoomToFit:) keyEquivalent:@""] autorelease]];
- menuItem = [[[NSMenuItem alloc] initWithTitle:@"View" action:nil keyEquivalent:@""] autorelease];
- [menuItem setSubmenu:menu];
- [[NSApp mainMenu] addItem:menuItem];
-
- // Window menu
- menu = [[NSMenu alloc] initWithTitle:@"Window"];
- [menu addItem: [[[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"] autorelease]]; // Miniaturize
- menuItem = [[[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""] autorelease];
- [menuItem setSubmenu:menu];
- [[NSApp mainMenu] addItem:menuItem];
- [NSApp setWindowsMenu:menu];
-
- // Help menu
- menu = [[NSMenu alloc] initWithTitle:@"Help"];
- [menu addItem: [[[NSMenuItem alloc] initWithTitle:@"QEMU Documentation" action:@selector(showQEMUDoc:) keyEquivalent:@"?"] autorelease]]; // QEMU Help
- [menu addItem: [[[NSMenuItem alloc] initWithTitle:@"QEMU Technology" action:@selector(showQEMUTec:) keyEquivalent:@""] autorelease]]; // QEMU Help
- menuItem = [[[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""] autorelease];
- [menuItem setSubmenu:menu];
- [[NSApp mainMenu] addItem:menuItem];
-
- // Create an Application controller
- QemuCocoaAppController *appController = [[QemuCocoaAppController alloc] init];
- [NSApp setDelegate:appController];
-
- // Start the main event loop
- [NSApp run];
-
- [appController release];
- [pool release];
-
- return 0;
-}
-
-
-
-#pragma mark qemu
-static void cocoa_update(DisplayChangeListener *dcl,
- int x, int y, int w, int h)
-{
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-
- COCOA_DEBUG("qemu_cocoa: cocoa_update\n");
-
- NSRect rect;
- if ([cocoaView cdx] == 1.0) {
- rect = NSMakeRect(x, [cocoaView gscreen].height - y - h, w, h);
- } else {
- rect = NSMakeRect(
- x * [cocoaView cdx],
- ([cocoaView gscreen].height - y - h) * [cocoaView cdy],
- w * [cocoaView cdx],
- h * [cocoaView cdy]);
- }
- [cocoaView setNeedsDisplayInRect:rect];
-
- [pool release];
-}
-
-static void cocoa_switch(DisplayChangeListener *dcl,
- DisplaySurface *surface)
-{
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-
- COCOA_DEBUG("qemu_cocoa: cocoa_switch\n");
- [cocoaView switchSurface:surface];
- [pool release];
-}
-
-static void cocoa_refresh(DisplayChangeListener *dcl)
-{
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-
- COCOA_DEBUG("qemu_cocoa: cocoa_refresh\n");
- graphic_hw_update(NULL);
-
- if (qemu_input_is_absolute()) {
- if (![cocoaView isAbsoluteEnabled]) {
- if ([cocoaView isMouseGrabbed]) {
- [cocoaView ungrabMouse];
- }
- }
- [cocoaView setAbsoluteEnabled:YES];
- }
-
- NSDate *distantPast;
- NSEvent *event;
- distantPast = [NSDate distantPast];
- do {
- event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:distantPast
- inMode: NSDefaultRunLoopMode dequeue:YES];
- if (event != nil) {
- [cocoaView handleEvent:event];
- }
- } while(event != nil);
- [pool release];
-}
-
-static void cocoa_cleanup(void)
-{
- COCOA_DEBUG("qemu_cocoa: cocoa_cleanup\n");
- g_free(dcl);
-}
-
-static const DisplayChangeListenerOps dcl_ops = {
- .dpy_name = "cocoa",
- .dpy_gfx_update = cocoa_update,
- .dpy_gfx_switch = cocoa_switch,
- .dpy_refresh = cocoa_refresh,
-};
-
-/* Returns a name for a given console */
-static NSString * getConsoleName(QemuConsole * console)
-{
- return [NSString stringWithFormat: @"%s", qemu_console_get_label(console)];
-}
-
-/* Add an entry to the View menu for each console */
-static void add_console_menu_entries(void)
-{
- NSMenu *menu;
- NSMenuItem *menuItem;
- int index = 0;
-
- menu = [[[NSApp mainMenu] itemWithTitle:@"View"] submenu];
-
- [menu addItem:[NSMenuItem separatorItem]];
-
- while (qemu_console_lookup_by_index(index) != NULL) {
- menuItem = [[[NSMenuItem alloc] initWithTitle: getConsoleName(qemu_console_lookup_by_index(index))
- action: @selector(displayConsole:) keyEquivalent: @""] autorelease];
- [menuItem setTag: index];
- [menu addItem: menuItem];
- index++;
- }
-}
-
-/* Make menu items for all removable devices.
- * Each device is given an 'Eject' and 'Change' menu item.
- */
-static void addRemovableDevicesMenuItems(void)
-{
- NSMenu *menu;
- NSMenuItem *menuItem;
- BlockInfoList *currentDevice, *pointerToFree;
- NSString *deviceName;
-
- currentDevice = qmp_query_block(NULL);
- pointerToFree = currentDevice;
- if(currentDevice == NULL) {
- NSBeep();
- QEMU_Alert(@"Failed to query for block devices!");
- return;
- }
-
- menu = [[[NSApp mainMenu] itemWithTitle:@"Machine"] submenu];
-
- // Add a separator between related groups of menu items
- [menu addItem:[NSMenuItem separatorItem]];
-
- // Set the attributes to the "Removable Media" menu item
- NSString *titleString = @"Removable Media";
- NSMutableAttributedString *attString=[[NSMutableAttributedString alloc] initWithString:titleString];
- NSColor *newColor = [NSColor blackColor];
- NSFontManager *fontManager = [NSFontManager sharedFontManager];
- NSFont *font = [fontManager fontWithFamily:@"Helvetica"
- traits:NSBoldFontMask|NSItalicFontMask
- weight:0
- size:14];
- [attString addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, [titleString length])];
- [attString addAttribute:NSForegroundColorAttributeName value:newColor range:NSMakeRange(0, [titleString length])];
- [attString addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInt: 1] range:NSMakeRange(0, [titleString length])];
-
- // Add the "Removable Media" menu item
- menuItem = [NSMenuItem new];
- [menuItem setAttributedTitle: attString];
- [menuItem setEnabled: NO];
- [menu addItem: menuItem];
-
- /* Loop thru all the block devices in the emulator */
- while (currentDevice) {
- deviceName = [[NSString stringWithFormat: @"%s", currentDevice->value->device] retain];
-
- if(currentDevice->value->removable) {
- menuItem = [[NSMenuItem alloc] initWithTitle: [NSString stringWithFormat: @"Change %s...", currentDevice->value->device]
- action: @selector(changeDeviceMedia:)
- keyEquivalent: @""];
- [menu addItem: menuItem];
- [menuItem setRepresentedObject: deviceName];
- [menuItem autorelease];
-
- menuItem = [[NSMenuItem alloc] initWithTitle: [NSString stringWithFormat: @"Eject %s", currentDevice->value->device]
- action: @selector(ejectDeviceMedia:)
- keyEquivalent: @""];
- [menu addItem: menuItem];
- [menuItem setRepresentedObject: deviceName];
- [menuItem autorelease];
- }
- currentDevice = currentDevice->next;
- }
- qapi_free_BlockInfoList(pointerToFree);
-}
-
-void cocoa_display_init(DisplayState *ds, int full_screen)
-{
- COCOA_DEBUG("qemu_cocoa: cocoa_display_init\n");
-
- /* if fullscreen mode is to be used */
- if (full_screen == true) {
- [NSApp activateIgnoringOtherApps: YES];
- [(QemuCocoaAppController *)[[NSApplication sharedApplication] delegate] toggleFullScreen: nil];
- }
-
- dcl = g_malloc0(sizeof(DisplayChangeListener));
-
- // register vga output callbacks
- dcl->ops = &dcl_ops;
- register_displaychangelistener(dcl);
-
- // register cleanup function
- atexit(cocoa_cleanup);
-
- /* At this point QEMU has created all the consoles, so we can add View
- * menu entries for them.
- */
- add_console_menu_entries();
-
- /* Give all removable devices a menu item.
- * Has to be called after QEMU has started to
- * find out what removable devices it has.
- */
- addRemovableDevicesMenuItems();
-}
diff --git a/qemu/ui/console-gl.c b/qemu/ui/console-gl.c
deleted file mode 100644
index 74b1bed6e..000000000
--- a/qemu/ui/console-gl.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * QEMU graphical console -- opengl helper bits
- *
- * Copyright (c) 2014 Red Hat
- *
- * Authors:
- * Gerd Hoffmann <kraxel@redhat.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "ui/console.h"
-#include "ui/shader.h"
-
-#include "shader/texture-blit-vert.h"
-#include "shader/texture-blit-frag.h"
-
-struct ConsoleGLState {
- GLint texture_blit_prog;
- GLint texture_blit_vao;
-};
-
-/* ---------------------------------------------------------------------- */
-
-ConsoleGLState *console_gl_init_context(void)
-{
- ConsoleGLState *gls = g_new0(ConsoleGLState, 1);
-
- gls->texture_blit_prog = qemu_gl_create_compile_link_program
- (texture_blit_vert_src, texture_blit_frag_src);
- if (!gls->texture_blit_prog) {
- exit(1);
- }
-
- gls->texture_blit_vao =
- qemu_gl_init_texture_blit(gls->texture_blit_prog);
-
- return gls;
-}
-
-void console_gl_fini_context(ConsoleGLState *gls)
-{
- if (!gls) {
- return;
- }
- g_free(gls);
-}
-
-bool console_gl_check_format(DisplayChangeListener *dcl,
- pixman_format_code_t format)
-{
- switch (format) {
- case PIXMAN_BE_b8g8r8x8:
- case PIXMAN_BE_b8g8r8a8:
- case PIXMAN_r5g6b5:
- return true;
- default:
- return false;
- }
-}
-
-void surface_gl_create_texture(ConsoleGLState *gls,
- DisplaySurface *surface)
-{
- assert(gls);
- assert(surface_stride(surface) % surface_bytes_per_pixel(surface) == 0);
-
- switch (surface->format) {
- case PIXMAN_BE_b8g8r8x8:
- case PIXMAN_BE_b8g8r8a8:
- surface->glformat = GL_BGRA_EXT;
- surface->gltype = GL_UNSIGNED_BYTE;
- break;
- case PIXMAN_r5g6b5:
- surface->glformat = GL_RGB;
- surface->gltype = GL_UNSIGNED_SHORT_5_6_5;
- break;
- default:
- g_assert_not_reached();
- }
-
- glGenTextures(1, &surface->texture);
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, surface->texture);
- glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT,
- surface_stride(surface) / surface_bytes_per_pixel(surface));
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
- surface_width(surface),
- surface_height(surface),
- 0, surface->glformat, surface->gltype,
- surface_data(surface));
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-}
-
-void surface_gl_update_texture(ConsoleGLState *gls,
- DisplaySurface *surface,
- int x, int y, int w, int h)
-{
- uint8_t *data = (void *)surface_data(surface);
-
- assert(gls);
-
- glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT,
- surface_stride(surface) / surface_bytes_per_pixel(surface));
- glTexSubImage2D(GL_TEXTURE_2D, 0,
- x, y, w, h,
- surface->glformat, surface->gltype,
- data + surface_stride(surface) * y
- + surface_bytes_per_pixel(surface) * x);
-}
-
-void surface_gl_render_texture(ConsoleGLState *gls,
- DisplaySurface *surface)
-{
- assert(gls);
-
- glClearColor(0.1f, 0.1f, 0.1f, 0.0f);
- glClear(GL_COLOR_BUFFER_BIT);
-
- qemu_gl_run_texture_blit(gls->texture_blit_prog,
- gls->texture_blit_vao);
-}
-
-void surface_gl_destroy_texture(ConsoleGLState *gls,
- DisplaySurface *surface)
-{
- if (!surface || !surface->texture) {
- return;
- }
- glDeleteTextures(1, &surface->texture);
- surface->texture = 0;
-}
-
-void surface_gl_setup_viewport(ConsoleGLState *gls,
- DisplaySurface *surface,
- int ww, int wh)
-{
- int gw, gh, stripe;
- float sw, sh;
-
- assert(gls);
-
- gw = surface_width(surface);
- gh = surface_height(surface);
-
- sw = (float)ww/gw;
- sh = (float)wh/gh;
- if (sw < sh) {
- stripe = wh - wh*sw/sh;
- glViewport(0, stripe / 2, ww, wh - stripe);
- } else {
- stripe = ww - ww*sh/sw;
- glViewport(stripe / 2, 0, ww - stripe, wh);
- }
-}
diff --git a/qemu/ui/console.c b/qemu/ui/console.c
deleted file mode 100644
index bf385790b..000000000
--- a/qemu/ui/console.c
+++ /dev/null
@@ -1,2168 +0,0 @@
-/*
- * QEMU graphical console
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "ui/console.h"
-#include "hw/qdev-core.h"
-#include "qemu/timer.h"
-#include "qmp-commands.h"
-#include "sysemu/char.h"
-#include "trace.h"
-#include "exec/memory.h"
-
-#define DEFAULT_BACKSCROLL 512
-#define CONSOLE_CURSOR_PERIOD 500
-
-typedef struct TextAttributes {
- uint8_t fgcol:4;
- uint8_t bgcol:4;
- uint8_t bold:1;
- uint8_t uline:1;
- uint8_t blink:1;
- uint8_t invers:1;
- uint8_t unvisible:1;
-} TextAttributes;
-
-typedef struct TextCell {
- uint8_t ch;
- TextAttributes t_attrib;
-} TextCell;
-
-#define MAX_ESC_PARAMS 3
-
-enum TTYState {
- TTY_STATE_NORM,
- TTY_STATE_ESC,
- TTY_STATE_CSI,
-};
-
-typedef struct QEMUFIFO {
- uint8_t *buf;
- int buf_size;
- int count, wptr, rptr;
-} QEMUFIFO;
-
-static int qemu_fifo_write(QEMUFIFO *f, const uint8_t *buf, int len1)
-{
- int l, len;
-
- l = f->buf_size - f->count;
- if (len1 > l)
- len1 = l;
- len = len1;
- while (len > 0) {
- l = f->buf_size - f->wptr;
- if (l > len)
- l = len;
- memcpy(f->buf + f->wptr, buf, l);
- f->wptr += l;
- if (f->wptr >= f->buf_size)
- f->wptr = 0;
- buf += l;
- len -= l;
- }
- f->count += len1;
- return len1;
-}
-
-static int qemu_fifo_read(QEMUFIFO *f, uint8_t *buf, int len1)
-{
- int l, len;
-
- if (len1 > f->count)
- len1 = f->count;
- len = len1;
- while (len > 0) {
- l = f->buf_size - f->rptr;
- if (l > len)
- l = len;
- memcpy(buf, f->buf + f->rptr, l);
- f->rptr += l;
- if (f->rptr >= f->buf_size)
- f->rptr = 0;
- buf += l;
- len -= l;
- }
- f->count -= len1;
- return len1;
-}
-
-typedef enum {
- GRAPHIC_CONSOLE,
- TEXT_CONSOLE,
- TEXT_CONSOLE_FIXED_SIZE
-} console_type_t;
-
-struct QemuConsole {
- Object parent;
-
- int index;
- console_type_t console_type;
- DisplayState *ds;
- DisplaySurface *surface;
- int dcls;
- DisplayChangeListener *gl;
-
- /* Graphic console state. */
- Object *device;
- uint32_t head;
- QemuUIInfo ui_info;
- QEMUTimer *ui_timer;
- const GraphicHwOps *hw_ops;
- void *hw;
-
- /* Text console state */
- int width;
- int height;
- int total_height;
- int backscroll_height;
- int x, y;
- int x_saved, y_saved;
- int y_displayed;
- int y_base;
- TextAttributes t_attrib_default; /* default text attributes */
- TextAttributes t_attrib; /* currently active text attributes */
- TextCell *cells;
- int text_x[2], text_y[2], cursor_invalidate;
- int echo;
-
- int update_x0;
- int update_y0;
- int update_x1;
- int update_y1;
-
- enum TTYState state;
- int esc_params[MAX_ESC_PARAMS];
- int nb_esc_params;
-
- CharDriverState *chr;
- /* fifo for key pressed */
- QEMUFIFO out_fifo;
- uint8_t out_fifo_buf[16];
- QEMUTimer *kbd_timer;
-};
-
-struct DisplayState {
- QEMUTimer *gui_timer;
- uint64_t last_update;
- uint64_t update_interval;
- bool refreshing;
- bool have_gfx;
- bool have_text;
-
- QLIST_HEAD(, DisplayChangeListener) listeners;
-};
-
-static DisplayState *display_state;
-static QemuConsole *active_console;
-static QemuConsole **consoles;
-static int nb_consoles = 0;
-static bool cursor_visible_phase;
-static QEMUTimer *cursor_timer;
-
-static void text_console_do_init(CharDriverState *chr, DisplayState *ds);
-static void dpy_refresh(DisplayState *s);
-static DisplayState *get_alloc_displaystate(void);
-static void text_console_update_cursor_timer(void);
-static void text_console_update_cursor(void *opaque);
-
-static void gui_update(void *opaque)
-{
- uint64_t interval = GUI_REFRESH_INTERVAL_IDLE;
- uint64_t dcl_interval;
- DisplayState *ds = opaque;
- DisplayChangeListener *dcl;
- int i;
-
- ds->refreshing = true;
- dpy_refresh(ds);
- ds->refreshing = false;
-
- QLIST_FOREACH(dcl, &ds->listeners, next) {
- dcl_interval = dcl->update_interval ?
- dcl->update_interval : GUI_REFRESH_INTERVAL_DEFAULT;
- if (interval > dcl_interval) {
- interval = dcl_interval;
- }
- }
- if (ds->update_interval != interval) {
- ds->update_interval = interval;
- for (i = 0; i < nb_consoles; i++) {
- if (consoles[i]->hw_ops->update_interval) {
- consoles[i]->hw_ops->update_interval(consoles[i]->hw, interval);
- }
- }
- trace_console_refresh(interval);
- }
- ds->last_update = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
- timer_mod(ds->gui_timer, ds->last_update + interval);
-}
-
-static void gui_setup_refresh(DisplayState *ds)
-{
- DisplayChangeListener *dcl;
- bool need_timer = false;
- bool have_gfx = false;
- bool have_text = false;
-
- QLIST_FOREACH(dcl, &ds->listeners, next) {
- if (dcl->ops->dpy_refresh != NULL) {
- need_timer = true;
- }
- if (dcl->ops->dpy_gfx_update != NULL) {
- have_gfx = true;
- }
- if (dcl->ops->dpy_text_update != NULL) {
- have_text = true;
- }
- }
-
- if (need_timer && ds->gui_timer == NULL) {
- ds->gui_timer = timer_new_ms(QEMU_CLOCK_REALTIME, gui_update, ds);
- timer_mod(ds->gui_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
- }
- if (!need_timer && ds->gui_timer != NULL) {
- timer_del(ds->gui_timer);
- timer_free(ds->gui_timer);
- ds->gui_timer = NULL;
- }
-
- ds->have_gfx = have_gfx;
- ds->have_text = have_text;
-}
-
-void graphic_hw_update(QemuConsole *con)
-{
- if (!con) {
- con = active_console;
- }
- if (con && con->hw_ops->gfx_update) {
- con->hw_ops->gfx_update(con->hw);
- }
-}
-
-void graphic_hw_gl_block(QemuConsole *con, bool block)
-{
- if (!con) {
- con = active_console;
- }
- if (con && con->hw_ops->gl_block) {
- con->hw_ops->gl_block(con->hw, block);
- }
-}
-
-void graphic_hw_invalidate(QemuConsole *con)
-{
- if (!con) {
- con = active_console;
- }
- if (con && con->hw_ops->invalidate) {
- con->hw_ops->invalidate(con->hw);
- }
-}
-
-static void ppm_save(const char *filename, DisplaySurface *ds,
- Error **errp)
-{
- int width = pixman_image_get_width(ds->image);
- int height = pixman_image_get_height(ds->image);
- int fd;
- FILE *f;
- int y;
- int ret;
- pixman_image_t *linebuf;
-
- trace_ppm_save(filename, ds);
- fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
- if (fd == -1) {
- error_setg(errp, "failed to open file '%s': %s", filename,
- strerror(errno));
- return;
- }
- f = fdopen(fd, "wb");
- ret = fprintf(f, "P6\n%d %d\n%d\n", width, height, 255);
- if (ret < 0) {
- linebuf = NULL;
- goto write_err;
- }
- linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, width);
- for (y = 0; y < height; y++) {
- qemu_pixman_linebuf_fill(linebuf, ds->image, width, 0, y);
- clearerr(f);
- ret = fwrite(pixman_image_get_data(linebuf), 1,
- pixman_image_get_stride(linebuf), f);
- (void)ret;
- if (ferror(f)) {
- goto write_err;
- }
- }
-
-out:
- qemu_pixman_image_unref(linebuf);
- fclose(f);
- return;
-
-write_err:
- error_setg(errp, "failed to write to file '%s': %s", filename,
- strerror(errno));
- unlink(filename);
- goto out;
-}
-
-void qmp_screendump(const char *filename, Error **errp)
-{
- QemuConsole *con = qemu_console_lookup_by_index(0);
- DisplaySurface *surface;
-
- if (con == NULL) {
- error_setg(errp, "There is no QemuConsole I can screendump from.");
- return;
- }
-
- graphic_hw_update(con);
- surface = qemu_console_surface(con);
- ppm_save(filename, surface, errp);
-}
-
-void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata)
-{
- if (!con) {
- con = active_console;
- }
- if (con && con->hw_ops->text_update) {
- con->hw_ops->text_update(con->hw, chardata);
- }
-}
-
-static void vga_fill_rect(QemuConsole *con,
- int posx, int posy, int width, int height,
- pixman_color_t color)
-{
- DisplaySurface *surface = qemu_console_surface(con);
- pixman_rectangle16_t rect = {
- .x = posx, .y = posy, .width = width, .height = height
- };
-
- pixman_image_fill_rectangles(PIXMAN_OP_SRC, surface->image,
- &color, 1, &rect);
-}
-
-/* copy from (xs, ys) to (xd, yd) a rectangle of size (w, h) */
-static void vga_bitblt(QemuConsole *con,
- int xs, int ys, int xd, int yd, int w, int h)
-{
- DisplaySurface *surface = qemu_console_surface(con);
-
- pixman_image_composite(PIXMAN_OP_SRC,
- surface->image, NULL, surface->image,
- xs, ys, 0, 0, xd, yd, w, h);
-}
-
-/***********************************************************/
-/* basic char display */
-
-#define FONT_HEIGHT 16
-#define FONT_WIDTH 8
-
-#include "vgafont.h"
-
-#define QEMU_RGB(r, g, b) \
- { .red = r << 8, .green = g << 8, .blue = b << 8, .alpha = 0xffff }
-
-static const pixman_color_t color_table_rgb[2][8] = {
- { /* dark */
- [QEMU_COLOR_BLACK] = QEMU_RGB(0x00, 0x00, 0x00), /* black */
- [QEMU_COLOR_BLUE] = QEMU_RGB(0x00, 0x00, 0xaa), /* blue */
- [QEMU_COLOR_GREEN] = QEMU_RGB(0x00, 0xaa, 0x00), /* green */
- [QEMU_COLOR_CYAN] = QEMU_RGB(0x00, 0xaa, 0xaa), /* cyan */
- [QEMU_COLOR_RED] = QEMU_RGB(0xaa, 0x00, 0x00), /* red */
- [QEMU_COLOR_MAGENTA] = QEMU_RGB(0xaa, 0x00, 0xaa), /* magenta */
- [QEMU_COLOR_YELLOW] = QEMU_RGB(0xaa, 0xaa, 0x00), /* yellow */
- [QEMU_COLOR_WHITE] = QEMU_RGB(0xaa, 0xaa, 0xaa), /* white */
- },
- { /* bright */
- [QEMU_COLOR_BLACK] = QEMU_RGB(0x00, 0x00, 0x00), /* black */
- [QEMU_COLOR_BLUE] = QEMU_RGB(0x00, 0x00, 0xff), /* blue */
- [QEMU_COLOR_GREEN] = QEMU_RGB(0x00, 0xff, 0x00), /* green */
- [QEMU_COLOR_CYAN] = QEMU_RGB(0x00, 0xff, 0xff), /* cyan */
- [QEMU_COLOR_RED] = QEMU_RGB(0xff, 0x00, 0x00), /* red */
- [QEMU_COLOR_MAGENTA] = QEMU_RGB(0xff, 0x00, 0xff), /* magenta */
- [QEMU_COLOR_YELLOW] = QEMU_RGB(0xff, 0xff, 0x00), /* yellow */
- [QEMU_COLOR_WHITE] = QEMU_RGB(0xff, 0xff, 0xff), /* white */
- }
-};
-
-static void vga_putcharxy(QemuConsole *s, int x, int y, int ch,
- TextAttributes *t_attrib)
-{
- static pixman_image_t *glyphs[256];
- DisplaySurface *surface = qemu_console_surface(s);
- pixman_color_t fgcol, bgcol;
-
- if (t_attrib->invers) {
- bgcol = color_table_rgb[t_attrib->bold][t_attrib->fgcol];
- fgcol = color_table_rgb[t_attrib->bold][t_attrib->bgcol];
- } else {
- fgcol = color_table_rgb[t_attrib->bold][t_attrib->fgcol];
- bgcol = color_table_rgb[t_attrib->bold][t_attrib->bgcol];
- }
-
- if (!glyphs[ch]) {
- glyphs[ch] = qemu_pixman_glyph_from_vgafont(FONT_HEIGHT, vgafont16, ch);
- }
- qemu_pixman_glyph_render(glyphs[ch], surface->image,
- &fgcol, &bgcol, x, y, FONT_WIDTH, FONT_HEIGHT);
-}
-
-static void text_console_resize(QemuConsole *s)
-{
- TextCell *cells, *c, *c1;
- int w1, x, y, last_width;
-
- last_width = s->width;
- s->width = surface_width(s->surface) / FONT_WIDTH;
- s->height = surface_height(s->surface) / FONT_HEIGHT;
-
- w1 = last_width;
- if (s->width < w1)
- w1 = s->width;
-
- cells = g_new(TextCell, s->width * s->total_height);
- for(y = 0; y < s->total_height; y++) {
- c = &cells[y * s->width];
- if (w1 > 0) {
- c1 = &s->cells[y * last_width];
- for(x = 0; x < w1; x++) {
- *c++ = *c1++;
- }
- }
- for(x = w1; x < s->width; x++) {
- c->ch = ' ';
- c->t_attrib = s->t_attrib_default;
- c++;
- }
- }
- g_free(s->cells);
- s->cells = cells;
-}
-
-static inline void text_update_xy(QemuConsole *s, int x, int y)
-{
- s->text_x[0] = MIN(s->text_x[0], x);
- s->text_x[1] = MAX(s->text_x[1], x);
- s->text_y[0] = MIN(s->text_y[0], y);
- s->text_y[1] = MAX(s->text_y[1], y);
-}
-
-static void invalidate_xy(QemuConsole *s, int x, int y)
-{
- if (!qemu_console_is_visible(s)) {
- return;
- }
- if (s->update_x0 > x * FONT_WIDTH)
- s->update_x0 = x * FONT_WIDTH;
- if (s->update_y0 > y * FONT_HEIGHT)
- s->update_y0 = y * FONT_HEIGHT;
- if (s->update_x1 < (x + 1) * FONT_WIDTH)
- s->update_x1 = (x + 1) * FONT_WIDTH;
- if (s->update_y1 < (y + 1) * FONT_HEIGHT)
- s->update_y1 = (y + 1) * FONT_HEIGHT;
-}
-
-static void update_xy(QemuConsole *s, int x, int y)
-{
- TextCell *c;
- int y1, y2;
-
- if (s->ds->have_text) {
- text_update_xy(s, x, y);
- }
-
- y1 = (s->y_base + y) % s->total_height;
- y2 = y1 - s->y_displayed;
- if (y2 < 0) {
- y2 += s->total_height;
- }
- if (y2 < s->height) {
- c = &s->cells[y1 * s->width + x];
- vga_putcharxy(s, x, y2, c->ch,
- &(c->t_attrib));
- invalidate_xy(s, x, y2);
- }
-}
-
-static void console_show_cursor(QemuConsole *s, int show)
-{
- TextCell *c;
- int y, y1;
- int x = s->x;
-
- if (s->ds->have_text) {
- s->cursor_invalidate = 1;
- }
-
- if (x >= s->width) {
- x = s->width - 1;
- }
- y1 = (s->y_base + s->y) % s->total_height;
- y = y1 - s->y_displayed;
- if (y < 0) {
- y += s->total_height;
- }
- if (y < s->height) {
- c = &s->cells[y1 * s->width + x];
- if (show && cursor_visible_phase) {
- TextAttributes t_attrib = s->t_attrib_default;
- t_attrib.invers = !(t_attrib.invers); /* invert fg and bg */
- vga_putcharxy(s, x, y, c->ch, &t_attrib);
- } else {
- vga_putcharxy(s, x, y, c->ch, &(c->t_attrib));
- }
- invalidate_xy(s, x, y);
- }
-}
-
-static void console_refresh(QemuConsole *s)
-{
- DisplaySurface *surface = qemu_console_surface(s);
- TextCell *c;
- int x, y, y1;
-
- if (s->ds->have_text) {
- s->text_x[0] = 0;
- s->text_y[0] = 0;
- s->text_x[1] = s->width - 1;
- s->text_y[1] = s->height - 1;
- s->cursor_invalidate = 1;
- }
-
- vga_fill_rect(s, 0, 0, surface_width(surface), surface_height(surface),
- color_table_rgb[0][QEMU_COLOR_BLACK]);
- y1 = s->y_displayed;
- for (y = 0; y < s->height; y++) {
- c = s->cells + y1 * s->width;
- for (x = 0; x < s->width; x++) {
- vga_putcharxy(s, x, y, c->ch,
- &(c->t_attrib));
- c++;
- }
- if (++y1 == s->total_height) {
- y1 = 0;
- }
- }
- console_show_cursor(s, 1);
- dpy_gfx_update(s, 0, 0,
- surface_width(surface), surface_height(surface));
-}
-
-static void console_scroll(QemuConsole *s, int ydelta)
-{
- int i, y1;
-
- if (ydelta > 0) {
- for(i = 0; i < ydelta; i++) {
- if (s->y_displayed == s->y_base)
- break;
- if (++s->y_displayed == s->total_height)
- s->y_displayed = 0;
- }
- } else {
- ydelta = -ydelta;
- i = s->backscroll_height;
- if (i > s->total_height - s->height)
- i = s->total_height - s->height;
- y1 = s->y_base - i;
- if (y1 < 0)
- y1 += s->total_height;
- for(i = 0; i < ydelta; i++) {
- if (s->y_displayed == y1)
- break;
- if (--s->y_displayed < 0)
- s->y_displayed = s->total_height - 1;
- }
- }
- console_refresh(s);
-}
-
-static void console_put_lf(QemuConsole *s)
-{
- TextCell *c;
- int x, y1;
-
- s->y++;
- if (s->y >= s->height) {
- s->y = s->height - 1;
-
- if (s->y_displayed == s->y_base) {
- if (++s->y_displayed == s->total_height)
- s->y_displayed = 0;
- }
- if (++s->y_base == s->total_height)
- s->y_base = 0;
- if (s->backscroll_height < s->total_height)
- s->backscroll_height++;
- y1 = (s->y_base + s->height - 1) % s->total_height;
- c = &s->cells[y1 * s->width];
- for(x = 0; x < s->width; x++) {
- c->ch = ' ';
- c->t_attrib = s->t_attrib_default;
- c++;
- }
- if (s->y_displayed == s->y_base) {
- if (s->ds->have_text) {
- s->text_x[0] = 0;
- s->text_y[0] = 0;
- s->text_x[1] = s->width - 1;
- s->text_y[1] = s->height - 1;
- }
-
- vga_bitblt(s, 0, FONT_HEIGHT, 0, 0,
- s->width * FONT_WIDTH,
- (s->height - 1) * FONT_HEIGHT);
- vga_fill_rect(s, 0, (s->height - 1) * FONT_HEIGHT,
- s->width * FONT_WIDTH, FONT_HEIGHT,
- color_table_rgb[0][s->t_attrib_default.bgcol]);
- s->update_x0 = 0;
- s->update_y0 = 0;
- s->update_x1 = s->width * FONT_WIDTH;
- s->update_y1 = s->height * FONT_HEIGHT;
- }
- }
-}
-
-/* Set console attributes depending on the current escape codes.
- * NOTE: I know this code is not very efficient (checking every color for it
- * self) but it is more readable and better maintainable.
- */
-static void console_handle_escape(QemuConsole *s)
-{
- int i;
-
- for (i=0; i<s->nb_esc_params; i++) {
- switch (s->esc_params[i]) {
- case 0: /* reset all console attributes to default */
- s->t_attrib = s->t_attrib_default;
- break;
- case 1:
- s->t_attrib.bold = 1;
- break;
- case 4:
- s->t_attrib.uline = 1;
- break;
- case 5:
- s->t_attrib.blink = 1;
- break;
- case 7:
- s->t_attrib.invers = 1;
- break;
- case 8:
- s->t_attrib.unvisible = 1;
- break;
- case 22:
- s->t_attrib.bold = 0;
- break;
- case 24:
- s->t_attrib.uline = 0;
- break;
- case 25:
- s->t_attrib.blink = 0;
- break;
- case 27:
- s->t_attrib.invers = 0;
- break;
- case 28:
- s->t_attrib.unvisible = 0;
- break;
- /* set foreground color */
- case 30:
- s->t_attrib.fgcol = QEMU_COLOR_BLACK;
- break;
- case 31:
- s->t_attrib.fgcol = QEMU_COLOR_RED;
- break;
- case 32:
- s->t_attrib.fgcol = QEMU_COLOR_GREEN;
- break;
- case 33:
- s->t_attrib.fgcol = QEMU_COLOR_YELLOW;
- break;
- case 34:
- s->t_attrib.fgcol = QEMU_COLOR_BLUE;
- break;
- case 35:
- s->t_attrib.fgcol = QEMU_COLOR_MAGENTA;
- break;
- case 36:
- s->t_attrib.fgcol = QEMU_COLOR_CYAN;
- break;
- case 37:
- s->t_attrib.fgcol = QEMU_COLOR_WHITE;
- break;
- /* set background color */
- case 40:
- s->t_attrib.bgcol = QEMU_COLOR_BLACK;
- break;
- case 41:
- s->t_attrib.bgcol = QEMU_COLOR_RED;
- break;
- case 42:
- s->t_attrib.bgcol = QEMU_COLOR_GREEN;
- break;
- case 43:
- s->t_attrib.bgcol = QEMU_COLOR_YELLOW;
- break;
- case 44:
- s->t_attrib.bgcol = QEMU_COLOR_BLUE;
- break;
- case 45:
- s->t_attrib.bgcol = QEMU_COLOR_MAGENTA;
- break;
- case 46:
- s->t_attrib.bgcol = QEMU_COLOR_CYAN;
- break;
- case 47:
- s->t_attrib.bgcol = QEMU_COLOR_WHITE;
- break;
- }
- }
-}
-
-static void console_clear_xy(QemuConsole *s, int x, int y)
-{
- int y1 = (s->y_base + y) % s->total_height;
- TextCell *c = &s->cells[y1 * s->width + x];
- c->ch = ' ';
- c->t_attrib = s->t_attrib_default;
- update_xy(s, x, y);
-}
-
-static void console_put_one(QemuConsole *s, int ch)
-{
- TextCell *c;
- int y1;
- if (s->x >= s->width) {
- /* line wrap */
- s->x = 0;
- console_put_lf(s);
- }
- y1 = (s->y_base + s->y) % s->total_height;
- c = &s->cells[y1 * s->width + s->x];
- c->ch = ch;
- c->t_attrib = s->t_attrib;
- update_xy(s, s->x, s->y);
- s->x++;
-}
-
-static void console_respond_str(QemuConsole *s, const char *buf)
-{
- while (*buf) {
- console_put_one(s, *buf);
- buf++;
- }
-}
-
-/* set cursor, checking bounds */
-static void set_cursor(QemuConsole *s, int x, int y)
-{
- if (x < 0) {
- x = 0;
- }
- if (y < 0) {
- y = 0;
- }
- if (y >= s->height) {
- y = s->height - 1;
- }
- if (x >= s->width) {
- x = s->width - 1;
- }
-
- s->x = x;
- s->y = y;
-}
-
-static void console_putchar(QemuConsole *s, int ch)
-{
- int i;
- int x, y;
- char response[40];
-
- switch(s->state) {
- case TTY_STATE_NORM:
- switch(ch) {
- case '\r': /* carriage return */
- s->x = 0;
- break;
- case '\n': /* newline */
- console_put_lf(s);
- break;
- case '\b': /* backspace */
- if (s->x > 0)
- s->x--;
- break;
- case '\t': /* tabspace */
- if (s->x + (8 - (s->x % 8)) > s->width) {
- s->x = 0;
- console_put_lf(s);
- } else {
- s->x = s->x + (8 - (s->x % 8));
- }
- break;
- case '\a': /* alert aka. bell */
- /* TODO: has to be implemented */
- break;
- case 14:
- /* SI (shift in), character set 0 (ignored) */
- break;
- case 15:
- /* SO (shift out), character set 1 (ignored) */
- break;
- case 27: /* esc (introducing an escape sequence) */
- s->state = TTY_STATE_ESC;
- break;
- default:
- console_put_one(s, ch);
- break;
- }
- break;
- case TTY_STATE_ESC: /* check if it is a terminal escape sequence */
- if (ch == '[') {
- for(i=0;i<MAX_ESC_PARAMS;i++)
- s->esc_params[i] = 0;
- s->nb_esc_params = 0;
- s->state = TTY_STATE_CSI;
- } else {
- s->state = TTY_STATE_NORM;
- }
- break;
- case TTY_STATE_CSI: /* handle escape sequence parameters */
- if (ch >= '0' && ch <= '9') {
- if (s->nb_esc_params < MAX_ESC_PARAMS) {
- int *param = &s->esc_params[s->nb_esc_params];
- int digit = (ch - '0');
-
- *param = (*param <= (INT_MAX - digit) / 10) ?
- *param * 10 + digit : INT_MAX;
- }
- } else {
- if (s->nb_esc_params < MAX_ESC_PARAMS)
- s->nb_esc_params++;
- if (ch == ';')
- break;
- trace_console_putchar_csi(s->esc_params[0], s->esc_params[1],
- ch, s->nb_esc_params);
- s->state = TTY_STATE_NORM;
- switch(ch) {
- case 'A':
- /* move cursor up */
- if (s->esc_params[0] == 0) {
- s->esc_params[0] = 1;
- }
- set_cursor(s, s->x, s->y - s->esc_params[0]);
- break;
- case 'B':
- /* move cursor down */
- if (s->esc_params[0] == 0) {
- s->esc_params[0] = 1;
- }
- set_cursor(s, s->x, s->y + s->esc_params[0]);
- break;
- case 'C':
- /* move cursor right */
- if (s->esc_params[0] == 0) {
- s->esc_params[0] = 1;
- }
- set_cursor(s, s->x + s->esc_params[0], s->y);
- break;
- case 'D':
- /* move cursor left */
- if (s->esc_params[0] == 0) {
- s->esc_params[0] = 1;
- }
- set_cursor(s, s->x - s->esc_params[0], s->y);
- break;
- case 'G':
- /* move cursor to column */
- set_cursor(s, s->esc_params[0] - 1, s->y);
- break;
- case 'f':
- case 'H':
- /* move cursor to row, column */
- set_cursor(s, s->esc_params[1] - 1, s->esc_params[0] - 1);
- break;
- case 'J':
- switch (s->esc_params[0]) {
- case 0:
- /* clear to end of screen */
- for (y = s->y; y < s->height; y++) {
- for (x = 0; x < s->width; x++) {
- if (y == s->y && x < s->x) {
- continue;
- }
- console_clear_xy(s, x, y);
- }
- }
- break;
- case 1:
- /* clear from beginning of screen */
- for (y = 0; y <= s->y; y++) {
- for (x = 0; x < s->width; x++) {
- if (y == s->y && x > s->x) {
- break;
- }
- console_clear_xy(s, x, y);
- }
- }
- break;
- case 2:
- /* clear entire screen */
- for (y = 0; y <= s->height; y++) {
- for (x = 0; x < s->width; x++) {
- console_clear_xy(s, x, y);
- }
- }
- break;
- }
- break;
- case 'K':
- switch (s->esc_params[0]) {
- case 0:
- /* clear to eol */
- for(x = s->x; x < s->width; x++) {
- console_clear_xy(s, x, s->y);
- }
- break;
- case 1:
- /* clear from beginning of line */
- for (x = 0; x <= s->x; x++) {
- console_clear_xy(s, x, s->y);
- }
- break;
- case 2:
- /* clear entire line */
- for(x = 0; x < s->width; x++) {
- console_clear_xy(s, x, s->y);
- }
- break;
- }
- break;
- case 'm':
- console_handle_escape(s);
- break;
- case 'n':
- switch (s->esc_params[0]) {
- case 5:
- /* report console status (always succeed)*/
- console_respond_str(s, "\033[0n");
- break;
- case 6:
- /* report cursor position */
- sprintf(response, "\033[%d;%dR",
- (s->y_base + s->y) % s->total_height + 1,
- s->x + 1);
- console_respond_str(s, response);
- break;
- }
- break;
- case 's':
- /* save cursor position */
- s->x_saved = s->x;
- s->y_saved = s->y;
- break;
- case 'u':
- /* restore cursor position */
- s->x = s->x_saved;
- s->y = s->y_saved;
- break;
- default:
- trace_console_putchar_unhandled(ch);
- break;
- }
- break;
- }
- }
-}
-
-void console_select(unsigned int index)
-{
- DisplayChangeListener *dcl;
- QemuConsole *s;
-
- trace_console_select(index);
- s = qemu_console_lookup_by_index(index);
- if (s) {
- DisplayState *ds = s->ds;
-
- active_console = s;
- if (ds->have_gfx) {
- QLIST_FOREACH(dcl, &ds->listeners, next) {
- if (dcl->con != NULL) {
- continue;
- }
- if (dcl->ops->dpy_gfx_switch) {
- dcl->ops->dpy_gfx_switch(dcl, s->surface);
- }
- }
- dpy_gfx_update(s, 0, 0, surface_width(s->surface),
- surface_height(s->surface));
- }
- if (ds->have_text) {
- dpy_text_resize(s, s->width, s->height);
- }
- text_console_update_cursor(NULL);
- }
-}
-
-static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
-{
- QemuConsole *s = chr->opaque;
- int i;
-
- s->update_x0 = s->width * FONT_WIDTH;
- s->update_y0 = s->height * FONT_HEIGHT;
- s->update_x1 = 0;
- s->update_y1 = 0;
- console_show_cursor(s, 0);
- for(i = 0; i < len; i++) {
- console_putchar(s, buf[i]);
- }
- console_show_cursor(s, 1);
- if (s->ds->have_gfx && s->update_x0 < s->update_x1) {
- dpy_gfx_update(s, s->update_x0, s->update_y0,
- s->update_x1 - s->update_x0,
- s->update_y1 - s->update_y0);
- }
- return len;
-}
-
-static void kbd_send_chars(void *opaque)
-{
- QemuConsole *s = opaque;
- int len;
- uint8_t buf[16];
-
- len = qemu_chr_be_can_write(s->chr);
- if (len > s->out_fifo.count)
- len = s->out_fifo.count;
- if (len > 0) {
- if (len > sizeof(buf))
- len = sizeof(buf);
- qemu_fifo_read(&s->out_fifo, buf, len);
- qemu_chr_be_write(s->chr, buf, len);
- }
- /* characters are pending: we send them a bit later (XXX:
- horrible, should change char device API) */
- if (s->out_fifo.count > 0) {
- timer_mod(s->kbd_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1);
- }
-}
-
-/* called when an ascii key is pressed */
-void kbd_put_keysym_console(QemuConsole *s, int keysym)
-{
- uint8_t buf[16], *q;
- int c;
-
- if (!s || (s->console_type == GRAPHIC_CONSOLE))
- return;
-
- switch(keysym) {
- case QEMU_KEY_CTRL_UP:
- console_scroll(s, -1);
- break;
- case QEMU_KEY_CTRL_DOWN:
- console_scroll(s, 1);
- break;
- case QEMU_KEY_CTRL_PAGEUP:
- console_scroll(s, -10);
- break;
- case QEMU_KEY_CTRL_PAGEDOWN:
- console_scroll(s, 10);
- break;
- default:
- /* convert the QEMU keysym to VT100 key string */
- q = buf;
- if (keysym >= 0xe100 && keysym <= 0xe11f) {
- *q++ = '\033';
- *q++ = '[';
- c = keysym - 0xe100;
- if (c >= 10)
- *q++ = '0' + (c / 10);
- *q++ = '0' + (c % 10);
- *q++ = '~';
- } else if (keysym >= 0xe120 && keysym <= 0xe17f) {
- *q++ = '\033';
- *q++ = '[';
- *q++ = keysym & 0xff;
- } else if (s->echo && (keysym == '\r' || keysym == '\n')) {
- console_puts(s->chr, (const uint8_t *) "\r", 1);
- *q++ = '\n';
- } else {
- *q++ = keysym;
- }
- if (s->echo) {
- console_puts(s->chr, buf, q - buf);
- }
- if (s->chr->chr_read) {
- qemu_fifo_write(&s->out_fifo, buf, q - buf);
- kbd_send_chars(s);
- }
- break;
- }
-}
-
-static const int qcode_to_keysym[Q_KEY_CODE__MAX] = {
- [Q_KEY_CODE_UP] = QEMU_KEY_UP,
- [Q_KEY_CODE_DOWN] = QEMU_KEY_DOWN,
- [Q_KEY_CODE_RIGHT] = QEMU_KEY_RIGHT,
- [Q_KEY_CODE_LEFT] = QEMU_KEY_LEFT,
- [Q_KEY_CODE_HOME] = QEMU_KEY_HOME,
- [Q_KEY_CODE_END] = QEMU_KEY_END,
- [Q_KEY_CODE_PGUP] = QEMU_KEY_PAGEUP,
- [Q_KEY_CODE_PGDN] = QEMU_KEY_PAGEDOWN,
- [Q_KEY_CODE_DELETE] = QEMU_KEY_DELETE,
-};
-
-bool kbd_put_qcode_console(QemuConsole *s, int qcode)
-{
- int keysym;
-
- keysym = qcode_to_keysym[qcode];
- if (keysym == 0) {
- return false;
- }
- kbd_put_keysym_console(s, keysym);
- return true;
-}
-
-void kbd_put_string_console(QemuConsole *s, const char *str, int len)
-{
- int i;
-
- for (i = 0; i < len && str[i]; i++) {
- kbd_put_keysym_console(s, str[i]);
- }
-}
-
-void kbd_put_keysym(int keysym)
-{
- kbd_put_keysym_console(active_console, keysym);
-}
-
-static void text_console_invalidate(void *opaque)
-{
- QemuConsole *s = (QemuConsole *) opaque;
-
- if (s->ds->have_text && s->console_type == TEXT_CONSOLE) {
- text_console_resize(s);
- }
- console_refresh(s);
-}
-
-static void text_console_update(void *opaque, console_ch_t *chardata)
-{
- QemuConsole *s = (QemuConsole *) opaque;
- int i, j, src;
-
- if (s->text_x[0] <= s->text_x[1]) {
- src = (s->y_base + s->text_y[0]) * s->width;
- chardata += s->text_y[0] * s->width;
- for (i = s->text_y[0]; i <= s->text_y[1]; i ++)
- for (j = 0; j < s->width; j++, src++) {
- console_write_ch(chardata ++,
- ATTR2CHTYPE(s->cells[src].ch,
- s->cells[src].t_attrib.fgcol,
- s->cells[src].t_attrib.bgcol,
- s->cells[src].t_attrib.bold));
- }
- dpy_text_update(s, s->text_x[0], s->text_y[0],
- s->text_x[1] - s->text_x[0], i - s->text_y[0]);
- s->text_x[0] = s->width;
- s->text_y[0] = s->height;
- s->text_x[1] = 0;
- s->text_y[1] = 0;
- }
- if (s->cursor_invalidate) {
- dpy_text_cursor(s, s->x, s->y);
- s->cursor_invalidate = 0;
- }
-}
-
-static QemuConsole *new_console(DisplayState *ds, console_type_t console_type,
- uint32_t head)
-{
- Object *obj;
- QemuConsole *s;
- int i;
-
- obj = object_new(TYPE_QEMU_CONSOLE);
- s = QEMU_CONSOLE(obj);
- s->head = head;
- object_property_add_link(obj, "device", TYPE_DEVICE,
- (Object **)&s->device,
- object_property_allow_set_link,
- OBJ_PROP_LINK_UNREF_ON_RELEASE,
- &error_abort);
- object_property_add_uint32_ptr(obj, "head",
- &s->head, &error_abort);
-
- if (!active_console || ((active_console->console_type != GRAPHIC_CONSOLE) &&
- (console_type == GRAPHIC_CONSOLE))) {
- active_console = s;
- }
- s->ds = ds;
- s->console_type = console_type;
-
- consoles = g_realloc(consoles, sizeof(*consoles) * (nb_consoles+1));
- if (console_type != GRAPHIC_CONSOLE) {
- s->index = nb_consoles;
- consoles[nb_consoles++] = s;
- } else {
- /* HACK: Put graphical consoles before text consoles. */
- for (i = nb_consoles; i > 0; i--) {
- if (consoles[i - 1]->console_type == GRAPHIC_CONSOLE)
- break;
- consoles[i] = consoles[i - 1];
- consoles[i]->index = i;
- }
- s->index = i;
- consoles[i] = s;
- nb_consoles++;
- }
- return s;
-}
-
-static void qemu_alloc_display(DisplaySurface *surface, int width, int height)
-{
- qemu_pixman_image_unref(surface->image);
- surface->image = NULL;
-
- surface->format = PIXMAN_x8r8g8b8;
- surface->image = pixman_image_create_bits(surface->format,
- width, height,
- NULL, width * 4);
- assert(surface->image != NULL);
-
- surface->flags = QEMU_ALLOCATED_FLAG;
-}
-
-DisplaySurface *qemu_create_displaysurface(int width, int height)
-{
- DisplaySurface *surface = g_new0(DisplaySurface, 1);
-
- trace_displaysurface_create(surface, width, height);
- qemu_alloc_display(surface, width, height);
- return surface;
-}
-
-DisplaySurface *qemu_create_displaysurface_from(int width, int height,
- pixman_format_code_t format,
- int linesize, uint8_t *data)
-{
- DisplaySurface *surface = g_new0(DisplaySurface, 1);
-
- trace_displaysurface_create_from(surface, width, height, format);
- surface->format = format;
- surface->image = pixman_image_create_bits(surface->format,
- width, height,
- (void *)data, linesize);
- assert(surface->image != NULL);
-
- return surface;
-}
-
-DisplaySurface *qemu_create_displaysurface_pixman(pixman_image_t *image)
-{
- DisplaySurface *surface = g_new0(DisplaySurface, 1);
-
- trace_displaysurface_create_pixman(surface);
- surface->format = pixman_image_get_format(image);
- surface->image = pixman_image_ref(image);
-
- return surface;
-}
-
-static void qemu_unmap_displaysurface_guestmem(pixman_image_t *image,
- void *unused)
-{
- void *data = pixman_image_get_data(image);
- uint32_t size = pixman_image_get_stride(image) *
- pixman_image_get_height(image);
- cpu_physical_memory_unmap(data, size, 0, 0);
-}
-
-DisplaySurface *qemu_create_displaysurface_guestmem(int width, int height,
- pixman_format_code_t format,
- int linesize, uint64_t addr)
-{
- DisplaySurface *surface;
- hwaddr size;
- void *data;
-
- if (linesize == 0) {
- linesize = width * PIXMAN_FORMAT_BPP(format) / 8;
- }
-
- size = (hwaddr)linesize * height;
- data = cpu_physical_memory_map(addr, &size, 0);
- if (size != (hwaddr)linesize * height) {
- cpu_physical_memory_unmap(data, size, 0, 0);
- return NULL;
- }
-
- surface = qemu_create_displaysurface_from
- (width, height, format, linesize, data);
- pixman_image_set_destroy_function
- (surface->image, qemu_unmap_displaysurface_guestmem, NULL);
-
- return surface;
-}
-
-static DisplaySurface *qemu_create_message_surface(int w, int h,
- const char *msg)
-{
- DisplaySurface *surface = qemu_create_displaysurface(w, h);
- pixman_color_t bg = color_table_rgb[0][QEMU_COLOR_BLACK];
- pixman_color_t fg = color_table_rgb[0][QEMU_COLOR_WHITE];
- pixman_image_t *glyph;
- int len, x, y, i;
-
- len = strlen(msg);
- x = (w / FONT_WIDTH - len) / 2;
- y = (h / FONT_HEIGHT - 1) / 2;
- for (i = 0; i < len; i++) {
- glyph = qemu_pixman_glyph_from_vgafont(FONT_HEIGHT, vgafont16, msg[i]);
- qemu_pixman_glyph_render(glyph, surface->image, &fg, &bg,
- x+i, y, FONT_WIDTH, FONT_HEIGHT);
- qemu_pixman_image_unref(glyph);
- }
- return surface;
-}
-
-void qemu_free_displaysurface(DisplaySurface *surface)
-{
- if (surface == NULL) {
- return;
- }
- trace_displaysurface_free(surface);
- qemu_pixman_image_unref(surface->image);
- g_free(surface);
-}
-
-bool console_has_gl(QemuConsole *con)
-{
- return con->gl != NULL;
-}
-
-void register_displaychangelistener(DisplayChangeListener *dcl)
-{
- static const char nodev[] =
- "This VM has no graphic display device.";
- static DisplaySurface *dummy;
- QemuConsole *con;
-
- if (dcl->ops->dpy_gl_ctx_create) {
- /* display has opengl support */
- assert(dcl->con);
- if (dcl->con->gl) {
- fprintf(stderr, "can't register two opengl displays (%s, %s)\n",
- dcl->ops->dpy_name, dcl->con->gl->ops->dpy_name);
- exit(1);
- }
- dcl->con->gl = dcl;
- }
-
- trace_displaychangelistener_register(dcl, dcl->ops->dpy_name);
- dcl->ds = get_alloc_displaystate();
- QLIST_INSERT_HEAD(&dcl->ds->listeners, dcl, next);
- gui_setup_refresh(dcl->ds);
- if (dcl->con) {
- dcl->con->dcls++;
- con = dcl->con;
- } else {
- con = active_console;
- }
- if (dcl->ops->dpy_gfx_switch) {
- if (con) {
- dcl->ops->dpy_gfx_switch(dcl, con->surface);
- } else {
- if (!dummy) {
- dummy = qemu_create_message_surface(640, 480, nodev);
- }
- dcl->ops->dpy_gfx_switch(dcl, dummy);
- }
- }
- text_console_update_cursor(NULL);
-}
-
-void update_displaychangelistener(DisplayChangeListener *dcl,
- uint64_t interval)
-{
- DisplayState *ds = dcl->ds;
-
- dcl->update_interval = interval;
- if (!ds->refreshing && ds->update_interval > interval) {
- timer_mod(ds->gui_timer, ds->last_update + interval);
- }
-}
-
-void unregister_displaychangelistener(DisplayChangeListener *dcl)
-{
- DisplayState *ds = dcl->ds;
- trace_displaychangelistener_unregister(dcl, dcl->ops->dpy_name);
- if (dcl->con) {
- dcl->con->dcls--;
- }
- QLIST_REMOVE(dcl, next);
- gui_setup_refresh(ds);
-}
-
-static void dpy_set_ui_info_timer(void *opaque)
-{
- QemuConsole *con = opaque;
-
- con->hw_ops->ui_info(con->hw, con->head, &con->ui_info);
-}
-
-bool dpy_ui_info_supported(QemuConsole *con)
-{
- return con->hw_ops->ui_info != NULL;
-}
-
-int dpy_set_ui_info(QemuConsole *con, QemuUIInfo *info)
-{
- assert(con != NULL);
- con->ui_info = *info;
- if (!dpy_ui_info_supported(con)) {
- return -1;
- }
-
- /*
- * Typically we get a flood of these as the user resizes the window.
- * Wait until the dust has settled (one second without updates), then
- * go notify the guest.
- */
- timer_mod(con->ui_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
- return 0;
-}
-
-void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h)
-{
- DisplayState *s = con->ds;
- DisplayChangeListener *dcl;
- int width = w;
- int height = h;
-
- if (con->surface) {
- width = surface_width(con->surface);
- height = surface_height(con->surface);
- }
- x = MAX(x, 0);
- y = MAX(y, 0);
- x = MIN(x, width);
- y = MIN(y, height);
- w = MIN(w, width - x);
- h = MIN(h, height - y);
-
- if (!qemu_console_is_visible(con)) {
- return;
- }
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (con != (dcl->con ? dcl->con : active_console)) {
- continue;
- }
- if (dcl->ops->dpy_gfx_update) {
- dcl->ops->dpy_gfx_update(dcl, x, y, w, h);
- }
- }
-}
-
-void dpy_gfx_replace_surface(QemuConsole *con,
- DisplaySurface *surface)
-{
- DisplayState *s = con->ds;
- DisplaySurface *old_surface = con->surface;
- DisplayChangeListener *dcl;
-
- con->surface = surface;
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (con != (dcl->con ? dcl->con : active_console)) {
- continue;
- }
- if (dcl->ops->dpy_gfx_switch) {
- dcl->ops->dpy_gfx_switch(dcl, surface);
- }
- }
- qemu_free_displaysurface(old_surface);
-}
-
-bool dpy_gfx_check_format(QemuConsole *con,
- pixman_format_code_t format)
-{
- DisplayChangeListener *dcl;
- DisplayState *s = con->ds;
-
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (dcl->con && dcl->con != con) {
- /* dcl bound to another console -> skip */
- continue;
- }
- if (dcl->ops->dpy_gfx_check_format) {
- if (!dcl->ops->dpy_gfx_check_format(dcl, format)) {
- return false;
- }
- } else {
- /* default is to whitelist native 32 bpp only */
- if (format != qemu_default_pixman_format(32, true)) {
- return false;
- }
- }
- }
- return true;
-}
-
-static void dpy_refresh(DisplayState *s)
-{
- DisplayChangeListener *dcl;
-
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (dcl->ops->dpy_refresh) {
- dcl->ops->dpy_refresh(dcl);
- }
- }
-}
-
-void dpy_gfx_copy(QemuConsole *con, int src_x, int src_y,
- int dst_x, int dst_y, int w, int h)
-{
- DisplayState *s = con->ds;
- DisplayChangeListener *dcl;
-
- if (!qemu_console_is_visible(con)) {
- return;
- }
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (con != (dcl->con ? dcl->con : active_console)) {
- continue;
- }
- if (dcl->ops->dpy_gfx_copy) {
- dcl->ops->dpy_gfx_copy(dcl, src_x, src_y, dst_x, dst_y, w, h);
- } else { /* TODO */
- dcl->ops->dpy_gfx_update(dcl, dst_x, dst_y, w, h);
- }
- }
-}
-
-void dpy_text_cursor(QemuConsole *con, int x, int y)
-{
- DisplayState *s = con->ds;
- DisplayChangeListener *dcl;
-
- if (!qemu_console_is_visible(con)) {
- return;
- }
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (con != (dcl->con ? dcl->con : active_console)) {
- continue;
- }
- if (dcl->ops->dpy_text_cursor) {
- dcl->ops->dpy_text_cursor(dcl, x, y);
- }
- }
-}
-
-void dpy_text_update(QemuConsole *con, int x, int y, int w, int h)
-{
- DisplayState *s = con->ds;
- DisplayChangeListener *dcl;
-
- if (!qemu_console_is_visible(con)) {
- return;
- }
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (con != (dcl->con ? dcl->con : active_console)) {
- continue;
- }
- if (dcl->ops->dpy_text_update) {
- dcl->ops->dpy_text_update(dcl, x, y, w, h);
- }
- }
-}
-
-void dpy_text_resize(QemuConsole *con, int w, int h)
-{
- DisplayState *s = con->ds;
- DisplayChangeListener *dcl;
-
- if (!qemu_console_is_visible(con)) {
- return;
- }
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (con != (dcl->con ? dcl->con : active_console)) {
- continue;
- }
- if (dcl->ops->dpy_text_resize) {
- dcl->ops->dpy_text_resize(dcl, w, h);
- }
- }
-}
-
-void dpy_mouse_set(QemuConsole *con, int x, int y, int on)
-{
- DisplayState *s = con->ds;
- DisplayChangeListener *dcl;
-
- if (!qemu_console_is_visible(con)) {
- return;
- }
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (con != (dcl->con ? dcl->con : active_console)) {
- continue;
- }
- if (dcl->ops->dpy_mouse_set) {
- dcl->ops->dpy_mouse_set(dcl, x, y, on);
- }
- }
-}
-
-void dpy_cursor_define(QemuConsole *con, QEMUCursor *cursor)
-{
- DisplayState *s = con->ds;
- DisplayChangeListener *dcl;
-
- if (!qemu_console_is_visible(con)) {
- return;
- }
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (con != (dcl->con ? dcl->con : active_console)) {
- continue;
- }
- if (dcl->ops->dpy_cursor_define) {
- dcl->ops->dpy_cursor_define(dcl, cursor);
- }
- }
-}
-
-bool dpy_cursor_define_supported(QemuConsole *con)
-{
- DisplayState *s = con->ds;
- DisplayChangeListener *dcl;
-
- QLIST_FOREACH(dcl, &s->listeners, next) {
- if (dcl->ops->dpy_cursor_define) {
- return true;
- }
- }
- return false;
-}
-
-QEMUGLContext dpy_gl_ctx_create(QemuConsole *con,
- struct QEMUGLParams *qparams)
-{
- assert(con->gl);
- return con->gl->ops->dpy_gl_ctx_create(con->gl, qparams);
-}
-
-void dpy_gl_ctx_destroy(QemuConsole *con, QEMUGLContext ctx)
-{
- assert(con->gl);
- con->gl->ops->dpy_gl_ctx_destroy(con->gl, ctx);
-}
-
-int dpy_gl_ctx_make_current(QemuConsole *con, QEMUGLContext ctx)
-{
- assert(con->gl);
- return con->gl->ops->dpy_gl_ctx_make_current(con->gl, ctx);
-}
-
-QEMUGLContext dpy_gl_ctx_get_current(QemuConsole *con)
-{
- assert(con->gl);
- return con->gl->ops->dpy_gl_ctx_get_current(con->gl);
-}
-
-void dpy_gl_scanout(QemuConsole *con,
- uint32_t backing_id, bool backing_y_0_top,
- uint32_t x, uint32_t y, uint32_t width, uint32_t height)
-{
- assert(con->gl);
- con->gl->ops->dpy_gl_scanout(con->gl, backing_id,
- backing_y_0_top,
- x, y, width, height);
-}
-
-void dpy_gl_update(QemuConsole *con,
- uint32_t x, uint32_t y, uint32_t w, uint32_t h)
-{
- assert(con->gl);
- con->gl->ops->dpy_gl_update(con->gl, x, y, w, h);
-}
-
-/***********************************************************/
-/* register display */
-
-/* console.c internal use only */
-static DisplayState *get_alloc_displaystate(void)
-{
- if (!display_state) {
- display_state = g_new0(DisplayState, 1);
- cursor_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
- text_console_update_cursor, NULL);
- }
- return display_state;
-}
-
-/*
- * Called by main(), after creating QemuConsoles
- * and before initializing ui (sdl/vnc/...).
- */
-DisplayState *init_displaystate(void)
-{
- gchar *name;
- int i;
-
- get_alloc_displaystate();
- for (i = 0; i < nb_consoles; i++) {
- if (consoles[i]->console_type != GRAPHIC_CONSOLE &&
- consoles[i]->ds == NULL) {
- text_console_do_init(consoles[i]->chr, display_state);
- }
-
- /* Hook up into the qom tree here (not in new_console()), once
- * all QemuConsoles are created and the order / numbering
- * doesn't change any more */
- name = g_strdup_printf("console[%d]", i);
- object_property_add_child(container_get(object_get_root(), "/backend"),
- name, OBJECT(consoles[i]), &error_abort);
- g_free(name);
- }
-
- return display_state;
-}
-
-void graphic_console_set_hwops(QemuConsole *con,
- const GraphicHwOps *hw_ops,
- void *opaque)
-{
- con->hw_ops = hw_ops;
- con->hw = opaque;
-}
-
-QemuConsole *graphic_console_init(DeviceState *dev, uint32_t head,
- const GraphicHwOps *hw_ops,
- void *opaque)
-{
- static const char noinit[] =
- "Guest has not initialized the display (yet).";
- int width = 640;
- int height = 480;
- QemuConsole *s;
- DisplayState *ds;
-
- ds = get_alloc_displaystate();
- trace_console_gfx_new();
- s = new_console(ds, GRAPHIC_CONSOLE, head);
- s->ui_timer = timer_new_ms(QEMU_CLOCK_REALTIME, dpy_set_ui_info_timer, s);
- graphic_console_set_hwops(s, hw_ops, opaque);
- if (dev) {
- object_property_set_link(OBJECT(s), OBJECT(dev), "device",
- &error_abort);
- }
-
- s->surface = qemu_create_message_surface(width, height, noinit);
- return s;
-}
-
-QemuConsole *qemu_console_lookup_by_index(unsigned int index)
-{
- if (index >= nb_consoles) {
- return NULL;
- }
- return consoles[index];
-}
-
-QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head)
-{
- Object *obj;
- uint32_t h;
- int i;
-
- for (i = 0; i < nb_consoles; i++) {
- if (!consoles[i]) {
- continue;
- }
- obj = object_property_get_link(OBJECT(consoles[i]),
- "device", &error_abort);
- if (DEVICE(obj) != dev) {
- continue;
- }
- h = object_property_get_int(OBJECT(consoles[i]),
- "head", &error_abort);
- if (h != head) {
- continue;
- }
- return consoles[i];
- }
- return NULL;
-}
-
-QemuConsole *qemu_console_lookup_by_device_name(const char *device_id,
- uint32_t head, Error **errp)
-{
- DeviceState *dev;
- QemuConsole *con;
-
- dev = qdev_find_recursive(sysbus_get_default(), device_id);
- if (dev == NULL) {
- error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
- "Device '%s' not found", device_id);
- return NULL;
- }
-
- con = qemu_console_lookup_by_device(dev, head);
- if (con == NULL) {
- error_setg(errp, "Device %s (head %d) is not bound to a QemuConsole",
- device_id, head);
- return NULL;
- }
-
- return con;
-}
-
-bool qemu_console_is_visible(QemuConsole *con)
-{
- return (con == active_console) || (con->dcls > 0);
-}
-
-bool qemu_console_is_graphic(QemuConsole *con)
-{
- if (con == NULL) {
- con = active_console;
- }
- return con && (con->console_type == GRAPHIC_CONSOLE);
-}
-
-bool qemu_console_is_fixedsize(QemuConsole *con)
-{
- if (con == NULL) {
- con = active_console;
- }
- return con && (con->console_type != TEXT_CONSOLE);
-}
-
-char *qemu_console_get_label(QemuConsole *con)
-{
- if (con->console_type == GRAPHIC_CONSOLE) {
- if (con->device) {
- return g_strdup(object_get_typename(con->device));
- }
- return g_strdup("VGA");
- } else {
- if (con->chr && con->chr->label) {
- return g_strdup(con->chr->label);
- }
- return g_strdup_printf("vc%d", con->index);
- }
-}
-
-int qemu_console_get_index(QemuConsole *con)
-{
- if (con == NULL) {
- con = active_console;
- }
- return con ? con->index : -1;
-}
-
-uint32_t qemu_console_get_head(QemuConsole *con)
-{
- if (con == NULL) {
- con = active_console;
- }
- return con ? con->head : -1;
-}
-
-QemuUIInfo *qemu_console_get_ui_info(QemuConsole *con)
-{
- assert(con != NULL);
- return &con->ui_info;
-}
-
-int qemu_console_get_width(QemuConsole *con, int fallback)
-{
- if (con == NULL) {
- con = active_console;
- }
- return con ? surface_width(con->surface) : fallback;
-}
-
-int qemu_console_get_height(QemuConsole *con, int fallback)
-{
- if (con == NULL) {
- con = active_console;
- }
- return con ? surface_height(con->surface) : fallback;
-}
-
-static void text_console_set_echo(CharDriverState *chr, bool echo)
-{
- QemuConsole *s = chr->opaque;
-
- s->echo = echo;
-}
-
-static void text_console_update_cursor_timer(void)
-{
- timer_mod(cursor_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME)
- + CONSOLE_CURSOR_PERIOD / 2);
-}
-
-static void text_console_update_cursor(void *opaque)
-{
- QemuConsole *s;
- int i, count = 0;
-
- cursor_visible_phase = !cursor_visible_phase;
-
- for (i = 0; i < nb_consoles; i++) {
- s = consoles[i];
- if (qemu_console_is_graphic(s) ||
- !qemu_console_is_visible(s)) {
- continue;
- }
- count++;
- graphic_hw_invalidate(s);
- }
-
- if (count) {
- text_console_update_cursor_timer();
- }
-}
-
-static const GraphicHwOps text_console_ops = {
- .invalidate = text_console_invalidate,
- .text_update = text_console_update,
-};
-
-static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
-{
- QemuConsole *s;
- int g_width = 80 * FONT_WIDTH;
- int g_height = 24 * FONT_HEIGHT;
-
- s = chr->opaque;
-
- chr->chr_write = console_puts;
-
- s->out_fifo.buf = s->out_fifo_buf;
- s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
- s->kbd_timer = timer_new_ms(QEMU_CLOCK_REALTIME, kbd_send_chars, s);
- s->ds = ds;
-
- s->y_displayed = 0;
- s->y_base = 0;
- s->total_height = DEFAULT_BACKSCROLL;
- s->x = 0;
- s->y = 0;
- if (!s->surface) {
- if (active_console && active_console->surface) {
- g_width = surface_width(active_console->surface);
- g_height = surface_height(active_console->surface);
- }
- s->surface = qemu_create_displaysurface(g_width, g_height);
- }
-
- s->hw_ops = &text_console_ops;
- s->hw = s;
-
- /* Set text attribute defaults */
- s->t_attrib_default.bold = 0;
- s->t_attrib_default.uline = 0;
- s->t_attrib_default.blink = 0;
- s->t_attrib_default.invers = 0;
- s->t_attrib_default.unvisible = 0;
- s->t_attrib_default.fgcol = QEMU_COLOR_WHITE;
- s->t_attrib_default.bgcol = QEMU_COLOR_BLACK;
- /* set current text attributes to default */
- s->t_attrib = s->t_attrib_default;
- text_console_resize(s);
-
- if (chr->label) {
- char msg[128];
- int len;
-
- s->t_attrib.bgcol = QEMU_COLOR_BLUE;
- len = snprintf(msg, sizeof(msg), "%s console\r\n", chr->label);
- console_puts(chr, (uint8_t*)msg, len);
- s->t_attrib = s->t_attrib_default;
- }
-
- qemu_chr_be_generic_open(chr);
- if (chr->init)
- chr->init(chr);
-}
-
-static CharDriverState *text_console_init(ChardevVC *vc, Error **errp)
-{
- ChardevCommon *common = qapi_ChardevVC_base(vc);
- CharDriverState *chr;
- QemuConsole *s;
- unsigned width = 0;
- unsigned height = 0;
-
- chr = qemu_chr_alloc(common, errp);
- if (!chr) {
- return NULL;
- }
-
- if (vc->has_width) {
- width = vc->width;
- } else if (vc->has_cols) {
- width = vc->cols * FONT_WIDTH;
- }
-
- if (vc->has_height) {
- height = vc->height;
- } else if (vc->has_rows) {
- height = vc->rows * FONT_HEIGHT;
- }
-
- trace_console_txt_new(width, height);
- if (width == 0 || height == 0) {
- s = new_console(NULL, TEXT_CONSOLE, 0);
- } else {
- s = new_console(NULL, TEXT_CONSOLE_FIXED_SIZE, 0);
- s->surface = qemu_create_displaysurface(width, height);
- }
-
- if (!s) {
- g_free(chr);
- error_setg(errp, "cannot create text console");
- return NULL;
- }
-
- s->chr = chr;
- chr->opaque = s;
- chr->chr_set_echo = text_console_set_echo;
- /* console/chardev init sometimes completes elsewhere in a 2nd
- * stage, so defer OPENED events until they are fully initialized
- */
- chr->explicit_be_open = true;
-
- if (display_state) {
- text_console_do_init(chr, display_state);
- }
- return chr;
-}
-
-static VcHandler *vc_handler = text_console_init;
-
-static CharDriverState *vc_init(const char *id, ChardevBackend *backend,
- ChardevReturn *ret, Error **errp)
-{
- return vc_handler(backend->u.vc.data, errp);
-}
-
-void register_vc_handler(VcHandler *handler)
-{
- vc_handler = handler;
-}
-
-void qemu_console_resize(QemuConsole *s, int width, int height)
-{
- DisplaySurface *surface;
-
- assert(s->console_type == GRAPHIC_CONSOLE);
- surface = qemu_create_displaysurface(width, height);
- dpy_gfx_replace_surface(s, surface);
-}
-
-void qemu_console_copy(QemuConsole *con, int src_x, int src_y,
- int dst_x, int dst_y, int w, int h)
-{
- assert(con->console_type == GRAPHIC_CONSOLE);
- dpy_gfx_copy(con, src_x, src_y, dst_x, dst_y, w, h);
-}
-
-DisplaySurface *qemu_console_surface(QemuConsole *console)
-{
- return console->surface;
-}
-
-PixelFormat qemu_default_pixelformat(int bpp)
-{
- pixman_format_code_t fmt = qemu_default_pixman_format(bpp, true);
- PixelFormat pf = qemu_pixelformat_from_pixman(fmt);
- return pf;
-}
-
-static void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend,
- Error **errp)
-{
- int val;
- ChardevVC *vc;
-
- vc = backend->u.vc.data = g_new0(ChardevVC, 1);
- qemu_chr_parse_common(opts, qapi_ChardevVC_base(vc));
-
- val = qemu_opt_get_number(opts, "width", 0);
- if (val != 0) {
- vc->has_width = true;
- vc->width = val;
- }
-
- val = qemu_opt_get_number(opts, "height", 0);
- if (val != 0) {
- vc->has_height = true;
- vc->height = val;
- }
-
- val = qemu_opt_get_number(opts, "cols", 0);
- if (val != 0) {
- vc->has_cols = true;
- vc->cols = val;
- }
-
- val = qemu_opt_get_number(opts, "rows", 0);
- if (val != 0) {
- vc->has_rows = true;
- vc->rows = val;
- }
-}
-
-static const TypeInfo qemu_console_info = {
- .name = TYPE_QEMU_CONSOLE,
- .parent = TYPE_OBJECT,
- .instance_size = sizeof(QemuConsole),
- .class_size = sizeof(QemuConsoleClass),
-};
-
-
-static void register_types(void)
-{
- type_register_static(&qemu_console_info);
- register_char_driver("vc", CHARDEV_BACKEND_KIND_VC, qemu_chr_parse_vc,
- vc_init);
-}
-
-type_init(register_types);
diff --git a/qemu/ui/curses.c b/qemu/ui/curses.c
deleted file mode 100644
index b47558956..000000000
--- a/qemu/ui/curses.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * QEMU curses/ncurses display driver
- *
- * Copyright (c) 2005 Andrzej Zaborowski <balrog@zabor.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu/osdep.h"
-#include <curses.h>
-
-#ifndef _WIN32
-#include <sys/ioctl.h>
-#include <termios.h>
-#endif
-
-#include "qemu-common.h"
-#include "ui/console.h"
-#include "ui/input.h"
-#include "sysemu/sysemu.h"
-
-#define FONT_HEIGHT 16
-#define FONT_WIDTH 8
-
-static DisplayChangeListener *dcl;
-static console_ch_t screen[160 * 100];
-static WINDOW *screenpad = NULL;
-static int width, height, gwidth, gheight, invalidate;
-static int px, py, sminx, sminy, smaxx, smaxy;
-
-chtype vga_to_curses[256];
-
-static void curses_update(DisplayChangeListener *dcl,
- int x, int y, int w, int h)
-{
- chtype *line;
-
- line = ((chtype *) screen) + y * width;
- for (h += y; y < h; y ++, line += width)
- mvwaddchnstr(screenpad, y, 0, line, width);
-
- pnoutrefresh(screenpad, py, px, sminy, sminx, smaxy - 1, smaxx - 1);
- refresh();
-}
-
-static void curses_calc_pad(void)
-{
- if (qemu_console_is_fixedsize(NULL)) {
- width = gwidth;
- height = gheight;
- } else {
- width = COLS;
- height = LINES;
- }
-
- if (screenpad)
- delwin(screenpad);
-
- clear();
- refresh();
-
- screenpad = newpad(height, width);
-
- if (width > COLS) {
- px = (width - COLS) / 2;
- sminx = 0;
- smaxx = COLS;
- } else {
- px = 0;
- sminx = (COLS - width) / 2;
- smaxx = sminx + width;
- }
-
- if (height > LINES) {
- py = (height - LINES) / 2;
- sminy = 0;
- smaxy = LINES;
- } else {
- py = 0;
- sminy = (LINES - height) / 2;
- smaxy = sminy + height;
- }
-}
-
-static void curses_resize(DisplayChangeListener *dcl,
- int width, int height)
-{
- if (width == gwidth && height == gheight) {
- return;
- }
-
- gwidth = width;
- gheight = height;
-
- curses_calc_pad();
-}
-
-#if !defined(_WIN32) && defined(SIGWINCH) && defined(KEY_RESIZE)
-static volatile sig_atomic_t got_sigwinch;
-static void curses_winch_check(void)
-{
- struct winsize {
- unsigned short ws_row;
- unsigned short ws_col;
- unsigned short ws_xpixel; /* unused */
- unsigned short ws_ypixel; /* unused */
- } ws;
-
- if (!got_sigwinch) {
- return;
- }
- got_sigwinch = false;
-
- if (ioctl(1, TIOCGWINSZ, &ws) == -1) {
- return;
- }
-
- resize_term(ws.ws_row, ws.ws_col);
- invalidate = 1;
-}
-
-static void curses_winch_handler(int signum)
-{
- got_sigwinch = true;
-}
-
-static void curses_winch_init(void)
-{
- struct sigaction old, winch = {
- .sa_handler = curses_winch_handler,
- };
- sigaction(SIGWINCH, &winch, &old);
-}
-#else
-static void curses_winch_check(void) {}
-static void curses_winch_init(void) {}
-#endif
-
-static void curses_cursor_position(DisplayChangeListener *dcl,
- int x, int y)
-{
- if (x >= 0) {
- x = sminx + x - px;
- y = sminy + y - py;
-
- if (x >= 0 && y >= 0 && x < COLS && y < LINES) {
- move(y, x);
- curs_set(1);
- /* it seems that curs_set(1) must always be called before
- * curs_set(2) for the latter to have effect */
- if (!qemu_console_is_graphic(NULL)) {
- curs_set(2);
- }
- return;
- }
- }
-
- curs_set(0);
-}
-
-/* generic keyboard conversion */
-
-#include "curses_keys.h"
-
-static kbd_layout_t *kbd_layout = NULL;
-
-static void curses_refresh(DisplayChangeListener *dcl)
-{
- int chr, nextchr, keysym, keycode, keycode_alt;
-
- curses_winch_check();
-
- if (invalidate) {
- clear();
- refresh();
- curses_calc_pad();
- graphic_hw_invalidate(NULL);
- invalidate = 0;
- }
-
- graphic_hw_text_update(NULL, screen);
-
- nextchr = ERR;
- while (1) {
- /* while there are any pending key strokes to process */
- if (nextchr == ERR)
- chr = getch();
- else {
- chr = nextchr;
- nextchr = ERR;
- }
-
- 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(dcl, 0, 0, width, height);
- continue;
- }
-#endif
-
- keycode = curses2keycode[chr];
- 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) {
- 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);
-
- invalidate = 1;
- continue;
- }
- }
- }
- }
-
- if (kbd_layout) {
- keysym = -1;
- if (chr < CURSES_KEYS)
- keysym = curses2keysym[chr];
-
- if (keysym == -1) {
- if (chr < ' ') {
- keysym = chr + '@';
- if (keysym >= 'A' && keysym <= 'Z')
- keysym += 'a' - 'A';
- keysym |= 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 (qemu_console_is_graphic(NULL)) {
- /* since terminals don't know about key press and release
- * events, we need to emit both for each key received */
- if (keycode & SHIFT) {
- qemu_input_event_send_key_number(NULL, SHIFT_CODE, true);
- qemu_input_event_send_key_delay(0);
- }
- if (keycode & CNTRL) {
- qemu_input_event_send_key_number(NULL, CNTRL_CODE, true);
- qemu_input_event_send_key_delay(0);
- }
- if (keycode & ALT) {
- qemu_input_event_send_key_number(NULL, ALT_CODE, true);
- qemu_input_event_send_key_delay(0);
- }
- if (keycode & ALTGR) {
- qemu_input_event_send_key_number(NULL, GREY | ALT_CODE, true);
- qemu_input_event_send_key_delay(0);
- }
-
- qemu_input_event_send_key_number(NULL, keycode & KEY_MASK, true);
- qemu_input_event_send_key_delay(0);
- qemu_input_event_send_key_number(NULL, keycode & KEY_MASK, false);
- qemu_input_event_send_key_delay(0);
-
- if (keycode & ALTGR) {
- qemu_input_event_send_key_number(NULL, GREY | ALT_CODE, false);
- qemu_input_event_send_key_delay(0);
- }
- if (keycode & ALT) {
- qemu_input_event_send_key_number(NULL, ALT_CODE, false);
- qemu_input_event_send_key_delay(0);
- }
- if (keycode & CNTRL) {
- qemu_input_event_send_key_number(NULL, CNTRL_CODE, false);
- qemu_input_event_send_key_delay(0);
- }
- if (keycode & SHIFT) {
- qemu_input_event_send_key_number(NULL, SHIFT_CODE, false);
- qemu_input_event_send_key_delay(0);
- }
- } else {
- keysym = curses2qemu[chr];
- if (keysym == -1)
- keysym = chr;
-
- kbd_put_keysym(keysym);
- }
- }
-}
-
-static void curses_atexit(void)
-{
- endwin();
-}
-
-static void curses_setup(void)
-{
- int i, colour_default[8] = {
- [QEMU_COLOR_BLACK] = COLOR_BLACK,
- [QEMU_COLOR_BLUE] = COLOR_BLUE,
- [QEMU_COLOR_GREEN] = COLOR_GREEN,
- [QEMU_COLOR_CYAN] = COLOR_CYAN,
- [QEMU_COLOR_RED] = COLOR_RED,
- [QEMU_COLOR_MAGENTA] = COLOR_MAGENTA,
- [QEMU_COLOR_YELLOW] = COLOR_YELLOW,
- [QEMU_COLOR_WHITE] = COLOR_WHITE,
- };
-
- /* input as raw as possible, let everything be interpreted
- * by the guest system */
- initscr(); noecho(); intrflush(stdscr, FALSE);
- nodelay(stdscr, TRUE); nonl(); keypad(stdscr, TRUE);
- start_color(); raw(); scrollok(stdscr, FALSE);
-
- /* Make color pair to match color format (3bits bg:3bits fg) */
- for (i = 0; i < 64; i++) {
- init_pair(i, colour_default[i & 7], colour_default[i >> 3]);
- }
- /* Set default color for more than 64 for safety. */
- for (i = 64; i < COLOR_PAIRS; i++) {
- init_pair(i, COLOR_WHITE, COLOR_BLACK);
- }
-
- /*
- * Setup mapping for vga to curses line graphics.
- * FIXME: for better font, have to use ncursesw and setlocale()
- */
-#if 0
- /* FIXME: map from where? */
- ACS_S1;
- ACS_S3;
- ACS_S7;
- ACS_S9;
-#endif
- /* ACS_* is not constant. So, we can't initialize statically. */
- vga_to_curses['\0'] = ' ';
- vga_to_curses[0x04] = ACS_DIAMOND;
- vga_to_curses[0x0a] = ACS_RARROW;
- vga_to_curses[0x0b] = ACS_LARROW;
- vga_to_curses[0x18] = ACS_UARROW;
- vga_to_curses[0x19] = ACS_DARROW;
- vga_to_curses[0x9c] = ACS_STERLING;
- vga_to_curses[0xb0] = ACS_BOARD;
- vga_to_curses[0xb1] = ACS_CKBOARD;
- vga_to_curses[0xb3] = ACS_VLINE;
- vga_to_curses[0xb4] = ACS_RTEE;
- vga_to_curses[0xbf] = ACS_URCORNER;
- vga_to_curses[0xc0] = ACS_LLCORNER;
- vga_to_curses[0xc1] = ACS_BTEE;
- vga_to_curses[0xc2] = ACS_TTEE;
- vga_to_curses[0xc3] = ACS_LTEE;
- vga_to_curses[0xc4] = ACS_HLINE;
- vga_to_curses[0xc5] = ACS_PLUS;
- vga_to_curses[0xce] = ACS_LANTERN;
- vga_to_curses[0xd8] = ACS_NEQUAL;
- vga_to_curses[0xd9] = ACS_LRCORNER;
- vga_to_curses[0xda] = ACS_ULCORNER;
- vga_to_curses[0xdb] = ACS_BLOCK;
- vga_to_curses[0xe3] = ACS_PI;
- vga_to_curses[0xf1] = ACS_PLMINUS;
- vga_to_curses[0xf2] = ACS_GEQUAL;
- vga_to_curses[0xf3] = ACS_LEQUAL;
- vga_to_curses[0xf8] = ACS_DEGREE;
- vga_to_curses[0xfe] = ACS_BULLET;
-}
-
-static void curses_keyboard_setup(void)
-{
-#if defined(__APPLE__)
- /* always use generic keymaps */
- if (!keyboard_layout)
- keyboard_layout = "en-us";
-#endif
- if(keyboard_layout) {
- kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
- if (!kbd_layout)
- exit(1);
- }
-}
-
-static const DisplayChangeListenerOps dcl_ops = {
- .dpy_name = "curses",
- .dpy_text_update = curses_update,
- .dpy_text_resize = curses_resize,
- .dpy_refresh = curses_refresh,
- .dpy_text_cursor = curses_cursor_position,
-};
-
-void curses_display_init(DisplayState *ds, int full_screen)
-{
-#ifndef _WIN32
- if (!isatty(1)) {
- fprintf(stderr, "We need a terminal output\n");
- exit(1);
- }
-#endif
-
- curses_setup();
- curses_keyboard_setup();
- atexit(curses_atexit);
-
- curses_winch_init();
-
- dcl = g_new0(DisplayChangeListener, 1);
- dcl->ops = &dcl_ops;
- register_displaychangelistener(dcl);
-
- invalidate = 1;
-}
diff --git a/qemu/ui/curses_keys.h b/qemu/ui/curses_keys.h
deleted file mode 100644
index f7467449b..000000000
--- a/qemu/ui/curses_keys.h
+++ /dev/null
@@ -1,518 +0,0 @@
-/*
- * Keycode and keysyms conversion tables for curses
- *
- * Copyright (c) 2005 Andrzej Zaborowski <balrog@zabor.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef QEMU_CURSES_KEYS_H
-#define QEMU_CURSES_KEYS_H 1
-
-#include <curses.h>
-#include "keymaps.h"
-
-
-#define KEY_MASK SCANCODE_KEYMASK
-#define GREY_CODE 0xe0
-#define GREY SCANCODE_GREY
-#define SHIFT_CODE 0x2a
-#define SHIFT SCANCODE_SHIFT
-#define CNTRL_CODE 0x1d
-#define CNTRL SCANCODE_CTRL
-#define ALT_CODE 0x38
-#define ALT SCANCODE_ALT
-#define ALTGR SCANCODE_ALTGR
-
-#define KEYSYM_MASK 0x0ffffff
-#define KEYSYM_SHIFT (SCANCODE_SHIFT << 16)
-#define KEYSYM_CNTRL (SCANCODE_CTRL << 16)
-#define KEYSYM_ALT (SCANCODE_ALT << 16)
-#define KEYSYM_ALTGR (SCANCODE_ALTGR << 16)
-
-/* curses won't detect a Control + Alt + 1, so use Alt + 1 */
-#define QEMU_KEY_CONSOLE0 (2 | ALT) /* (curses2keycode['1'] | ALT) */
-
-#define CURSES_KEYS KEY_MAX /* KEY_MAX defined in <curses.h> */
-
-static const int curses2keysym[CURSES_KEYS] = {
- [0 ... (CURSES_KEYS - 1)] = -1,
-
- [0x7f] = KEY_BACKSPACE,
- ['\r'] = KEY_ENTER,
- ['\n'] = KEY_ENTER,
- [27] = 27,
- [KEY_BTAB] = '\t' | KEYSYM_SHIFT,
- [KEY_SPREVIOUS] = KEY_PPAGE | KEYSYM_SHIFT,
- [KEY_SNEXT] = KEY_NPAGE | KEYSYM_SHIFT,
-};
-
-static const int curses2keycode[CURSES_KEYS] = {
- [0 ... (CURSES_KEYS - 1)] = -1,
-
- [0x01b] = 1, /* Escape */
- ['1'] = 2,
- ['2'] = 3,
- ['3'] = 4,
- ['4'] = 5,
- ['5'] = 6,
- ['6'] = 7,
- ['7'] = 8,
- ['8'] = 9,
- ['9'] = 10,
- ['0'] = 11,
- ['-'] = 12,
- ['='] = 13,
- [0x07f] = 14, /* Backspace */
- [KEY_BACKSPACE] = 14, /* Backspace */
-
- ['\t'] = 15, /* Tab */
- ['q'] = 16,
- ['w'] = 17,
- ['e'] = 18,
- ['r'] = 19,
- ['t'] = 20,
- ['y'] = 21,
- ['u'] = 22,
- ['i'] = 23,
- ['o'] = 24,
- ['p'] = 25,
- ['['] = 26,
- [']'] = 27,
- ['\n'] = 28, /* Return */
- ['\r'] = 28, /* Return */
- [KEY_ENTER] = 28, /* Return */
-
- ['a'] = 30,
- ['s'] = 31,
- ['d'] = 32,
- ['f'] = 33,
- ['g'] = 34,
- ['h'] = 35,
- ['j'] = 36,
- ['k'] = 37,
- ['l'] = 38,
- [';'] = 39,
- ['\''] = 40, /* Single quote */
- ['`'] = 41,
- ['\\'] = 43, /* Backslash */
-
- ['z'] = 44,
- ['x'] = 45,
- ['c'] = 46,
- ['v'] = 47,
- ['b'] = 48,
- ['n'] = 49,
- ['m'] = 50,
- [','] = 51,
- ['.'] = 52,
- ['/'] = 53,
-
- [' '] = 57,
-
- [KEY_F(1)] = 59, /* Function Key 1 */
- [KEY_F(2)] = 60, /* Function Key 2 */
- [KEY_F(3)] = 61, /* Function Key 3 */
- [KEY_F(4)] = 62, /* Function Key 4 */
- [KEY_F(5)] = 63, /* Function Key 5 */
- [KEY_F(6)] = 64, /* Function Key 6 */
- [KEY_F(7)] = 65, /* Function Key 7 */
- [KEY_F(8)] = 66, /* Function Key 8 */
- [KEY_F(9)] = 67, /* Function Key 9 */
- [KEY_F(10)] = 68, /* Function Key 10 */
- [KEY_F(11)] = 87, /* Function Key 11 */
- [KEY_F(12)] = 88, /* Function Key 12 */
-
- [KEY_HOME] = 71 | GREY, /* Home */
- [KEY_UP] = 72 | GREY, /* Up Arrow */
- [KEY_PPAGE] = 73 | GREY, /* Page Up */
- [KEY_LEFT] = 75 | GREY, /* Left Arrow */
- [KEY_RIGHT] = 77 | GREY, /* Right Arrow */
- [KEY_END] = 79 | GREY, /* End */
- [KEY_DOWN] = 80 | GREY, /* Down Arrow */
- [KEY_NPAGE] = 81 | GREY, /* Page Down */
- [KEY_IC] = 82 | GREY, /* Insert */
- [KEY_DC] = 83 | GREY, /* Delete */
-
- [KEY_SPREVIOUS] = 73 | GREY | SHIFT, /* Shift + Page Up */
- [KEY_SNEXT] = 81 | GREY | SHIFT, /* Shift + Page Down */
-
- ['!'] = 2 | SHIFT,
- ['@'] = 3 | SHIFT,
- ['#'] = 4 | SHIFT,
- ['$'] = 5 | SHIFT,
- ['%'] = 6 | SHIFT,
- ['^'] = 7 | SHIFT,
- ['&'] = 8 | SHIFT,
- ['*'] = 9 | SHIFT,
- ['('] = 10 | SHIFT,
- [')'] = 11 | SHIFT,
- ['_'] = 12 | SHIFT,
- ['+'] = 13 | SHIFT,
-
- [KEY_BTAB] = 15 | SHIFT, /* Shift + Tab */
- ['Q'] = 16 | SHIFT,
- ['W'] = 17 | SHIFT,
- ['E'] = 18 | SHIFT,
- ['R'] = 19 | SHIFT,
- ['T'] = 20 | SHIFT,
- ['Y'] = 21 | SHIFT,
- ['U'] = 22 | SHIFT,
- ['I'] = 23 | SHIFT,
- ['O'] = 24 | SHIFT,
- ['P'] = 25 | SHIFT,
- ['{'] = 26 | SHIFT,
- ['}'] = 27 | SHIFT,
-
- ['A'] = 30 | SHIFT,
- ['S'] = 31 | SHIFT,
- ['D'] = 32 | SHIFT,
- ['F'] = 33 | SHIFT,
- ['G'] = 34 | SHIFT,
- ['H'] = 35 | SHIFT,
- ['J'] = 36 | SHIFT,
- ['K'] = 37 | SHIFT,
- ['L'] = 38 | SHIFT,
- [':'] = 39 | SHIFT,
- ['"'] = 40 | SHIFT,
- ['~'] = 41 | SHIFT,
- ['|'] = 43 | SHIFT,
-
- ['Z'] = 44 | SHIFT,
- ['X'] = 45 | SHIFT,
- ['C'] = 46 | SHIFT,
- ['V'] = 47 | SHIFT,
- ['B'] = 48 | SHIFT,
- ['N'] = 49 | SHIFT,
- ['M'] = 50 | SHIFT,
- ['<'] = 51 | SHIFT,
- ['>'] = 52 | SHIFT,
- ['?'] = 53 | SHIFT,
-
- [KEY_F(13)] = 59 | SHIFT, /* Shift + Function Key 1 */
- [KEY_F(14)] = 60 | SHIFT, /* Shift + Function Key 2 */
- [KEY_F(15)] = 61 | SHIFT, /* Shift + Function Key 3 */
- [KEY_F(16)] = 62 | SHIFT, /* Shift + Function Key 4 */
- [KEY_F(17)] = 63 | SHIFT, /* Shift + Function Key 5 */
- [KEY_F(18)] = 64 | SHIFT, /* Shift + Function Key 6 */
- [KEY_F(19)] = 65 | SHIFT, /* Shift + Function Key 7 */
- [KEY_F(20)] = 66 | SHIFT, /* Shift + Function Key 8 */
- [KEY_F(21)] = 67 | SHIFT, /* Shift + Function Key 9 */
- [KEY_F(22)] = 68 | SHIFT, /* Shift + Function Key 10 */
- [KEY_F(23)] = 69 | SHIFT, /* Shift + Function Key 11 */
- [KEY_F(24)] = 70 | SHIFT, /* Shift + Function Key 12 */
-
- ['Q' - '@'] = 16 | CNTRL, /* Control + q */
- ['W' - '@'] = 17 | CNTRL, /* Control + w */
- ['E' - '@'] = 18 | CNTRL, /* Control + e */
- ['R' - '@'] = 19 | CNTRL, /* Control + r */
- ['T' - '@'] = 20 | CNTRL, /* Control + t */
- ['Y' - '@'] = 21 | CNTRL, /* Control + y */
- ['U' - '@'] = 22 | CNTRL, /* Control + u */
- /* Control + i collides with Tab */
- ['O' - '@'] = 24 | CNTRL, /* Control + o */
- ['P' - '@'] = 25 | CNTRL, /* Control + p */
-
- ['A' - '@'] = 30 | CNTRL, /* Control + a */
- ['S' - '@'] = 31 | CNTRL, /* Control + s */
- ['D' - '@'] = 32 | CNTRL, /* Control + d */
- ['F' - '@'] = 33 | CNTRL, /* Control + f */
- ['G' - '@'] = 34 | CNTRL, /* Control + g */
- ['H' - '@'] = 35 | CNTRL, /* Control + h */
- /* Control + j collides with Return */
- ['K' - '@'] = 37 | CNTRL, /* Control + k */
- ['L' - '@'] = 38 | CNTRL, /* Control + l */
-
- ['Z' - '@'] = 44 | CNTRL, /* Control + z */
- ['X' - '@'] = 45 | CNTRL, /* Control + x */
- ['C' - '@'] = 46 | CNTRL, /* Control + c */
- ['V' - '@'] = 47 | CNTRL, /* Control + v */
- ['B' - '@'] = 48 | CNTRL, /* Control + b */
- ['N' - '@'] = 49 | CNTRL, /* Control + n */
- /* Control + m collides with the keycode for Enter */
-
-};
-
-static const int curses2qemu[CURSES_KEYS] = {
- [0 ... (CURSES_KEYS - 1)] = -1,
-
- ['\n'] = '\n',
- ['\r'] = '\n',
-
- [0x07f] = QEMU_KEY_BACKSPACE,
-
- [KEY_DOWN] = QEMU_KEY_DOWN,
- [KEY_UP] = QEMU_KEY_UP,
- [KEY_LEFT] = QEMU_KEY_LEFT,
- [KEY_RIGHT] = QEMU_KEY_RIGHT,
- [KEY_HOME] = QEMU_KEY_HOME,
- [KEY_BACKSPACE] = QEMU_KEY_BACKSPACE,
-
- [KEY_DC] = QEMU_KEY_DELETE,
- [KEY_NPAGE] = QEMU_KEY_PAGEDOWN,
- [KEY_PPAGE] = QEMU_KEY_PAGEUP,
- [KEY_ENTER] = '\n',
- [KEY_END] = QEMU_KEY_END,
-
-};
-
-static const name2keysym_t name2keysym[] = {
- /* Plain ASCII */
- { "space", 0x020 },
- { "exclam", 0x021 },
- { "quotedbl", 0x022 },
- { "numbersign", 0x023 },
- { "dollar", 0x024 },
- { "percent", 0x025 },
- { "ampersand", 0x026 },
- { "apostrophe", 0x027 },
- { "parenleft", 0x028 },
- { "parenright", 0x029 },
- { "asterisk", 0x02a },
- { "plus", 0x02b },
- { "comma", 0x02c },
- { "minus", 0x02d },
- { "period", 0x02e },
- { "slash", 0x02f },
- { "0", 0x030 },
- { "1", 0x031 },
- { "2", 0x032 },
- { "3", 0x033 },
- { "4", 0x034 },
- { "5", 0x035 },
- { "6", 0x036 },
- { "7", 0x037 },
- { "8", 0x038 },
- { "9", 0x039 },
- { "colon", 0x03a },
- { "semicolon", 0x03b },
- { "less", 0x03c },
- { "equal", 0x03d },
- { "greater", 0x03e },
- { "question", 0x03f },
- { "at", 0x040 },
- { "A", 0x041 },
- { "B", 0x042 },
- { "C", 0x043 },
- { "D", 0x044 },
- { "E", 0x045 },
- { "F", 0x046 },
- { "G", 0x047 },
- { "H", 0x048 },
- { "I", 0x049 },
- { "J", 0x04a },
- { "K", 0x04b },
- { "L", 0x04c },
- { "M", 0x04d },
- { "N", 0x04e },
- { "O", 0x04f },
- { "P", 0x050 },
- { "Q", 0x051 },
- { "R", 0x052 },
- { "S", 0x053 },
- { "T", 0x054 },
- { "U", 0x055 },
- { "V", 0x056 },
- { "W", 0x057 },
- { "X", 0x058 },
- { "Y", 0x059 },
- { "Z", 0x05a },
- { "bracketleft", 0x05b },
- { "backslash", 0x05c },
- { "bracketright", 0x05d },
- { "asciicircum", 0x05e },
- { "underscore", 0x05f },
- { "grave", 0x060 },
- { "a", 0x061 },
- { "b", 0x062 },
- { "c", 0x063 },
- { "d", 0x064 },
- { "e", 0x065 },
- { "f", 0x066 },
- { "g", 0x067 },
- { "h", 0x068 },
- { "i", 0x069 },
- { "j", 0x06a },
- { "k", 0x06b },
- { "l", 0x06c },
- { "m", 0x06d },
- { "n", 0x06e },
- { "o", 0x06f },
- { "p", 0x070 },
- { "q", 0x071 },
- { "r", 0x072 },
- { "s", 0x073 },
- { "t", 0x074 },
- { "u", 0x075 },
- { "v", 0x076 },
- { "w", 0x077 },
- { "x", 0x078 },
- { "y", 0x079 },
- { "z", 0x07a },
- { "braceleft", 0x07b },
- { "bar", 0x07c },
- { "braceright", 0x07d },
- { "asciitilde", 0x07e },
-
- /* Latin-1 extensions */
- { "nobreakspace", 0x0a0 },
- { "exclamdown", 0x0a1 },
- { "cent", 0x0a2 },
- { "sterling", 0x0a3 },
- { "currency", 0x0a4 },
- { "yen", 0x0a5 },
- { "brokenbar", 0x0a6 },
- { "section", 0x0a7 },
- { "diaeresis", 0x0a8 },
- { "copyright", 0x0a9 },
- { "ordfeminine", 0x0aa },
- { "guillemotleft", 0x0ab },
- { "notsign", 0x0ac },
- { "hyphen", 0x0ad },
- { "registered", 0x0ae },
- { "macron", 0x0af },
- { "degree", 0x0b0 },
- { "plusminus", 0x0b1 },
- { "twosuperior", 0x0b2 },
- { "threesuperior", 0x0b3 },
- { "acute", 0x0b4 },
- { "mu", 0x0b5 },
- { "paragraph", 0x0b6 },
- { "periodcentered", 0x0b7 },
- { "cedilla", 0x0b8 },
- { "onesuperior", 0x0b9 },
- { "masculine", 0x0ba },
- { "guillemotright", 0x0bb },
- { "onequarter", 0x0bc },
- { "onehalf", 0x0bd },
- { "threequarters", 0x0be },
- { "questiondown", 0x0bf },
- { "Agrave", 0x0c0 },
- { "Aacute", 0x0c1 },
- { "Acircumflex", 0x0c2 },
- { "Atilde", 0x0c3 },
- { "Adiaeresis", 0x0c4 },
- { "Aring", 0x0c5 },
- { "AE", 0x0c6 },
- { "Ccedilla", 0x0c7 },
- { "Egrave", 0x0c8 },
- { "Eacute", 0x0c9 },
- { "Ecircumflex", 0x0ca },
- { "Ediaeresis", 0x0cb },
- { "Igrave", 0x0cc },
- { "Iacute", 0x0cd },
- { "Icircumflex", 0x0ce },
- { "Idiaeresis", 0x0cf },
- { "ETH", 0x0d0 },
- { "Eth", 0x0d0 },
- { "Ntilde", 0x0d1 },
- { "Ograve", 0x0d2 },
- { "Oacute", 0x0d3 },
- { "Ocircumflex", 0x0d4 },
- { "Otilde", 0x0d5 },
- { "Odiaeresis", 0x0d6 },
- { "multiply", 0x0d7 },
- { "Ooblique", 0x0d8 },
- { "Oslash", 0x0d8 },
- { "Ugrave", 0x0d9 },
- { "Uacute", 0x0da },
- { "Ucircumflex", 0x0db },
- { "Udiaeresis", 0x0dc },
- { "Yacute", 0x0dd },
- { "THORN", 0x0de },
- { "Thorn", 0x0de },
- { "ssharp", 0x0df },
- { "agrave", 0x0e0 },
- { "aacute", 0x0e1 },
- { "acircumflex", 0x0e2 },
- { "atilde", 0x0e3 },
- { "adiaeresis", 0x0e4 },
- { "aring", 0x0e5 },
- { "ae", 0x0e6 },
- { "ccedilla", 0x0e7 },
- { "egrave", 0x0e8 },
- { "eacute", 0x0e9 },
- { "ecircumflex", 0x0ea },
- { "ediaeresis", 0x0eb },
- { "igrave", 0x0ec },
- { "iacute", 0x0ed },
- { "icircumflex", 0x0ee },
- { "idiaeresis", 0x0ef },
- { "eth", 0x0f0 },
- { "ntilde", 0x0f1 },
- { "ograve", 0x0f2 },
- { "oacute", 0x0f3 },
- { "ocircumflex", 0x0f4 },
- { "otilde", 0x0f5 },
- { "odiaeresis", 0x0f6 },
- { "division", 0x0f7 },
- { "oslash", 0x0f8 },
- { "ooblique", 0x0f8 },
- { "ugrave", 0x0f9 },
- { "uacute", 0x0fa },
- { "ucircumflex", 0x0fb },
- { "udiaeresis", 0x0fc },
- { "yacute", 0x0fd },
- { "thorn", 0x0fe },
- { "ydiaeresis", 0x0ff },
-
- /* Special keys */
- { "BackSpace", KEY_BACKSPACE },
- { "Tab", '\t' },
- { "Return", KEY_ENTER },
- { "Right", KEY_RIGHT },
- { "Left", KEY_LEFT },
- { "Up", KEY_UP },
- { "Down", KEY_DOWN },
- { "Page_Down", KEY_NPAGE },
- { "Page_Up", KEY_PPAGE },
- { "Insert", KEY_IC },
- { "Delete", KEY_DC },
- { "Home", KEY_HOME },
- { "End", KEY_END },
- { "F1", KEY_F(1) },
- { "F2", KEY_F(2) },
- { "F3", KEY_F(3) },
- { "F4", KEY_F(4) },
- { "F5", KEY_F(5) },
- { "F6", KEY_F(6) },
- { "F7", KEY_F(7) },
- { "F8", KEY_F(8) },
- { "F9", KEY_F(9) },
- { "F10", KEY_F(10) },
- { "F11", KEY_F(11) },
- { "F12", KEY_F(12) },
- { "F13", KEY_F(13) },
- { "F14", KEY_F(14) },
- { "F15", KEY_F(15) },
- { "F16", KEY_F(16) },
- { "F17", KEY_F(17) },
- { "F18", KEY_F(18) },
- { "F19", KEY_F(19) },
- { "F20", KEY_F(20) },
- { "F21", KEY_F(21) },
- { "F22", KEY_F(22) },
- { "F23", KEY_F(23) },
- { "F24", KEY_F(24) },
- { "Escape", 27 },
-
- { NULL, 0 },
-};
-
-#endif
diff --git a/qemu/ui/cursor.c b/qemu/ui/cursor.c
deleted file mode 100644
index a276e01f1..000000000
--- a/qemu/ui/cursor.c
+++ /dev/null
@@ -1,212 +0,0 @@
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "ui/console.h"
-
-#include "cursor_hidden.xpm"
-#include "cursor_left_ptr.xpm"
-
-/* for creating built-in cursors */
-static QEMUCursor *cursor_parse_xpm(const char *xpm[])
-{
- QEMUCursor *c;
- uint32_t ctab[128];
- unsigned int width, height, colors, chars;
- unsigned int line = 0, i, r, g, b, x, y, pixel;
- char name[16];
- uint8_t idx;
-
- /* parse header line: width, height, #colors, #chars */
- if (sscanf(xpm[line], "%u %u %u %u",
- &width, &height, &colors, &chars) != 4) {
- fprintf(stderr, "%s: header parse error: \"%s\"\n",
- __FUNCTION__, xpm[line]);
- return NULL;
- }
- if (chars != 1) {
- fprintf(stderr, "%s: chars != 1 not supported\n", __FUNCTION__);
- return NULL;
- }
- line++;
-
- /* parse color table */
- for (i = 0; i < colors; i++, line++) {
- if (sscanf(xpm[line], "%c c %15s", &idx, name) == 2) {
- if (sscanf(name, "#%02x%02x%02x", &r, &g, &b) == 3) {
- ctab[idx] = (0xff << 24) | (b << 16) | (g << 8) | r;
- continue;
- }
- if (strcmp(name, "None") == 0) {
- ctab[idx] = 0x00000000;
- continue;
- }
- }
- fprintf(stderr, "%s: color parse error: \"%s\"\n",
- __FUNCTION__, xpm[line]);
- return NULL;
- }
-
- /* parse pixel data */
- c = cursor_alloc(width, height);
- for (pixel = 0, y = 0; y < height; y++, line++) {
- for (x = 0; x < height; x++, pixel++) {
- idx = xpm[line][x];
- c->data[pixel] = ctab[idx];
- }
- }
- return c;
-}
-
-/* nice for debugging */
-void cursor_print_ascii_art(QEMUCursor *c, const char *prefix)
-{
- uint32_t *data = c->data;
- int x,y;
-
- for (y = 0; y < c->height; y++) {
- fprintf(stderr, "%s: %2d: |", prefix, y);
- for (x = 0; x < c->width; x++, data++) {
- if ((*data & 0xff000000) != 0xff000000) {
- fprintf(stderr, " "); /* transparent */
- } else if ((*data & 0x00ffffff) == 0x00ffffff) {
- fprintf(stderr, "."); /* white */
- } else if ((*data & 0x00ffffff) == 0x00000000) {
- fprintf(stderr, "X"); /* black */
- } else {
- fprintf(stderr, "o"); /* other */
- }
- }
- fprintf(stderr, "|\n");
- }
-}
-
-QEMUCursor *cursor_builtin_hidden(void)
-{
- QEMUCursor *c;
-
- c = cursor_parse_xpm(cursor_hidden_xpm);
- return c;
-}
-
-QEMUCursor *cursor_builtin_left_ptr(void)
-{
- QEMUCursor *c;
-
- c = cursor_parse_xpm(cursor_left_ptr_xpm);
- return c;
-}
-
-QEMUCursor *cursor_alloc(int width, int height)
-{
- QEMUCursor *c;
- int datasize = width * height * sizeof(uint32_t);
-
- c = g_malloc0(sizeof(QEMUCursor) + datasize);
- c->width = width;
- c->height = height;
- c->refcount = 1;
- return c;
-}
-
-void cursor_get(QEMUCursor *c)
-{
- c->refcount++;
-}
-
-void cursor_put(QEMUCursor *c)
-{
- if (c == NULL)
- return;
- c->refcount--;
- if (c->refcount)
- return;
- g_free(c);
-}
-
-int cursor_get_mono_bpl(QEMUCursor *c)
-{
- return (c->width + 7) / 8;
-}
-
-void cursor_set_mono(QEMUCursor *c,
- uint32_t foreground, uint32_t background, uint8_t *image,
- int transparent, uint8_t *mask)
-{
- uint32_t *data = c->data;
- uint8_t bit;
- int x,y,bpl;
-
- bpl = cursor_get_mono_bpl(c);
- for (y = 0; y < c->height; y++) {
- bit = 0x80;
- for (x = 0; x < c->width; x++, data++) {
- if (transparent && mask[x/8] & bit) {
- *data = 0x00000000;
- } else if (!transparent && !(mask[x/8] & bit)) {
- *data = 0x00000000;
- } else if (image[x/8] & bit) {
- *data = 0xff000000 | foreground;
- } else {
- *data = 0xff000000 | background;
- }
- bit >>= 1;
- if (bit == 0) {
- bit = 0x80;
- }
- }
- mask += bpl;
- image += bpl;
- }
-}
-
-void cursor_get_mono_image(QEMUCursor *c, int foreground, uint8_t *image)
-{
- uint32_t *data = c->data;
- uint8_t bit;
- int x,y,bpl;
-
- bpl = cursor_get_mono_bpl(c);
- memset(image, 0, bpl * c->height);
- for (y = 0; y < c->height; y++) {
- bit = 0x80;
- for (x = 0; x < c->width; x++, data++) {
- if (((*data & 0xff000000) == 0xff000000) &&
- ((*data & 0x00ffffff) == foreground)) {
- image[x/8] |= bit;
- }
- bit >>= 1;
- if (bit == 0) {
- bit = 0x80;
- }
- }
- image += bpl;
- }
-}
-
-void cursor_get_mono_mask(QEMUCursor *c, int transparent, uint8_t *mask)
-{
- uint32_t *data = c->data;
- uint8_t bit;
- int x,y,bpl;
-
- bpl = cursor_get_mono_bpl(c);
- memset(mask, 0, bpl * c->height);
- for (y = 0; y < c->height; y++) {
- bit = 0x80;
- for (x = 0; x < c->width; x++, data++) {
- if ((*data & 0xff000000) != 0xff000000) {
- if (transparent != 0) {
- mask[x/8] |= bit;
- }
- } else {
- if (transparent == 0) {
- mask[x/8] |= bit;
- }
- }
- bit >>= 1;
- if (bit == 0) {
- bit = 0x80;
- }
- }
- mask += bpl;
- }
-}
diff --git a/qemu/ui/cursor_hidden.xpm b/qemu/ui/cursor_hidden.xpm
deleted file mode 100644
index 354e7a939..000000000
--- a/qemu/ui/cursor_hidden.xpm
+++ /dev/null
@@ -1,37 +0,0 @@
-/* XPM */
-static const char *cursor_hidden_xpm[] = {
- "32 32 1 1",
- " c None",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
-};
diff --git a/qemu/ui/cursor_left_ptr.xpm b/qemu/ui/cursor_left_ptr.xpm
deleted file mode 100644
index 6c9ada902..000000000
--- a/qemu/ui/cursor_left_ptr.xpm
+++ /dev/null
@@ -1,39 +0,0 @@
-/* XPM */
-static const char *cursor_left_ptr_xpm[] = {
- "32 32 3 1",
- "X c #000000",
- ". c #ffffff",
- " c None",
- "X ",
- "XX ",
- "X.X ",
- "X..X ",
- "X...X ",
- "X....X ",
- "X.....X ",
- "X......X ",
- "X.......X ",
- "X........X ",
- "X.....XXXXX ",
- "X..X..X ",
- "X.X X..X ",
- "XX X..X ",
- "X X..X ",
- " X..X ",
- " X..X ",
- " X..X ",
- " XX ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
-};
diff --git a/qemu/ui/egl-context.c b/qemu/ui/egl-context.c
deleted file mode 100644
index 3a02b68d1..000000000
--- a/qemu/ui/egl-context.c
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "ui/egl-context.h"
-
-QEMUGLContext qemu_egl_create_context(DisplayChangeListener *dcl,
- QEMUGLParams *params)
-{
- EGLContext ctx;
- EGLint ctx_att[] = {
- EGL_CONTEXT_CLIENT_VERSION, params->major_ver,
- EGL_CONTEXT_MINOR_VERSION_KHR, params->minor_ver,
- EGL_NONE
- };
-
- ctx = eglCreateContext(qemu_egl_display, qemu_egl_config,
- eglGetCurrentContext(), ctx_att);
- return ctx;
-}
-
-void qemu_egl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx)
-{
- eglDestroyContext(qemu_egl_display, ctx);
-}
-
-int qemu_egl_make_context_current(DisplayChangeListener *dcl,
- QEMUGLContext ctx)
-{
- return eglMakeCurrent(qemu_egl_display,
- EGL_NO_SURFACE, EGL_NO_SURFACE, ctx);
-}
-
-QEMUGLContext qemu_egl_get_current_context(DisplayChangeListener *dcl)
-{
- return eglGetCurrentContext();
-}
diff --git a/qemu/ui/egl-helpers.c b/qemu/ui/egl-helpers.c
deleted file mode 100644
index 558edfdeb..000000000
--- a/qemu/ui/egl-helpers.c
+++ /dev/null
@@ -1,269 +0,0 @@
-#include "qemu/osdep.h"
-#include <glob.h>
-#include <dirent.h>
-
-#include "ui/egl-helpers.h"
-
-EGLDisplay *qemu_egl_display;
-EGLConfig qemu_egl_config;
-
-/* ---------------------------------------------------------------------- */
-
-static bool egl_gles;
-static int egl_debug;
-
-#define egl_dbg(_x ...) \
- do { \
- if (egl_debug) { \
- fprintf(stderr, "egl: " _x); \
- } \
- } while (0);
-
-/* ---------------------------------------------------------------------- */
-
-#ifdef CONFIG_OPENGL_DMABUF
-
-int qemu_egl_rn_fd;
-struct gbm_device *qemu_egl_rn_gbm_dev;
-EGLContext qemu_egl_rn_ctx;
-
-int qemu_egl_rendernode_open(void)
-{
- DIR *dir;
- struct dirent *e;
- int r, fd;
- char *p;
-
- dir = opendir("/dev/dri");
- if (!dir) {
- return -1;
- }
-
- fd = -1;
- while ((e = readdir(dir))) {
- if (e->d_type != DT_CHR) {
- continue;
- }
-
- if (strncmp(e->d_name, "renderD", 7)) {
- continue;
- }
-
- r = asprintf(&p, "/dev/dri/%s", e->d_name);
- if (r < 0) {
- return -1;
- }
-
- r = open(p, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
- if (r < 0) {
- free(p);
- continue;
- }
- fd = r;
- free(p);
- break;
- }
-
- closedir(dir);
- if (fd < 0) {
- return -1;
- }
- return fd;
-}
-
-int egl_rendernode_init(void)
-{
- qemu_egl_rn_fd = -1;
-
- qemu_egl_rn_fd = qemu_egl_rendernode_open();
- if (qemu_egl_rn_fd == -1) {
- fprintf(stderr, "egl: no drm render node available\n");
- goto err;
- }
-
- qemu_egl_rn_gbm_dev = gbm_create_device(qemu_egl_rn_fd);
- if (!qemu_egl_rn_gbm_dev) {
- fprintf(stderr, "egl: gbm_create_device failed\n");
- goto err;
- }
-
- qemu_egl_init_dpy((EGLNativeDisplayType)qemu_egl_rn_gbm_dev, false, false);
-
- if (!epoxy_has_egl_extension(qemu_egl_display,
- "EGL_KHR_surfaceless_context")) {
- fprintf(stderr, "egl: EGL_KHR_surfaceless_context not supported\n");
- goto err;
- }
- if (!epoxy_has_egl_extension(qemu_egl_display,
- "EGL_MESA_image_dma_buf_export")) {
- fprintf(stderr, "egl: EGL_MESA_image_dma_buf_export not supported\n");
- goto err;
- }
-
- qemu_egl_rn_ctx = qemu_egl_init_ctx();
- if (!qemu_egl_rn_ctx) {
- fprintf(stderr, "egl: egl_init_ctx failed\n");
- goto err;
- }
-
- return 0;
-
-err:
- if (qemu_egl_rn_gbm_dev) {
- gbm_device_destroy(qemu_egl_rn_gbm_dev);
- }
- if (qemu_egl_rn_fd != -1) {
- close(qemu_egl_rn_fd);
- }
-
- return -1;
-}
-
-int egl_get_fd_for_texture(uint32_t tex_id, EGLint *stride, EGLint *fourcc)
-{
- EGLImageKHR image;
- EGLint num_planes, fd;
-
- image = eglCreateImageKHR(qemu_egl_display, eglGetCurrentContext(),
- EGL_GL_TEXTURE_2D_KHR,
- (EGLClientBuffer)(unsigned long)tex_id,
- NULL);
- if (!image) {
- return -1;
- }
-
- eglExportDMABUFImageQueryMESA(qemu_egl_display, image, fourcc,
- &num_planes, NULL);
- if (num_planes != 1) {
- eglDestroyImageKHR(qemu_egl_display, image);
- return -1;
- }
- eglExportDMABUFImageMESA(qemu_egl_display, image, &fd, stride, NULL);
- eglDestroyImageKHR(qemu_egl_display, image);
-
- return fd;
-}
-
-#endif /* CONFIG_OPENGL_DMABUF */
-
-/* ---------------------------------------------------------------------- */
-
-EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, Window win)
-{
- EGLSurface esurface;
- EGLBoolean b;
-
- egl_dbg("eglCreateWindowSurface (x11 win id 0x%lx) ...\n",
- (unsigned long) win);
- esurface = eglCreateWindowSurface(qemu_egl_display,
- qemu_egl_config,
- (EGLNativeWindowType)win, NULL);
- if (esurface == EGL_NO_SURFACE) {
- fprintf(stderr, "egl: eglCreateWindowSurface failed\n");
- return NULL;
- }
-
- b = eglMakeCurrent(qemu_egl_display, esurface, esurface, ectx);
- if (b == EGL_FALSE) {
- fprintf(stderr, "egl: eglMakeCurrent failed\n");
- return NULL;
- }
-
- return esurface;
-}
-
-/* ---------------------------------------------------------------------- */
-
-int qemu_egl_init_dpy(EGLNativeDisplayType dpy, bool gles, bool debug)
-{
- static const EGLint conf_att_gl[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
- EGL_RED_SIZE, 5,
- EGL_GREEN_SIZE, 5,
- EGL_BLUE_SIZE, 5,
- EGL_ALPHA_SIZE, 0,
- EGL_NONE,
- };
- static const EGLint conf_att_gles[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL_RED_SIZE, 5,
- EGL_GREEN_SIZE, 5,
- EGL_BLUE_SIZE, 5,
- EGL_ALPHA_SIZE, 0,
- EGL_NONE,
- };
- EGLint major, minor;
- EGLBoolean b;
- EGLint n;
-
- if (debug) {
- egl_debug = 1;
- setenv("EGL_LOG_LEVEL", "debug", true);
- setenv("LIBGL_DEBUG", "verbose", true);
- }
-
- egl_dbg("eglGetDisplay (dpy %p) ...\n", dpy);
- qemu_egl_display = eglGetDisplay(dpy);
- if (qemu_egl_display == EGL_NO_DISPLAY) {
- fprintf(stderr, "egl: eglGetDisplay failed\n");
- return -1;
- }
-
- egl_dbg("eglInitialize ...\n");
- b = eglInitialize(qemu_egl_display, &major, &minor);
- if (b == EGL_FALSE) {
- fprintf(stderr, "egl: eglInitialize failed\n");
- return -1;
- }
-
- egl_dbg("eglBindAPI ...\n");
- b = eglBindAPI(gles ? EGL_OPENGL_ES_API : EGL_OPENGL_API);
- if (b == EGL_FALSE) {
- fprintf(stderr, "egl: eglBindAPI failed\n");
- return -1;
- }
-
- egl_dbg("eglChooseConfig ...\n");
- b = eglChooseConfig(qemu_egl_display,
- gles ? conf_att_gles : conf_att_gl,
- &qemu_egl_config, 1, &n);
- if (b == EGL_FALSE || n != 1) {
- fprintf(stderr, "egl: eglChooseConfig failed\n");
- return -1;
- }
-
- egl_gles = gles;
- return 0;
-}
-
-EGLContext qemu_egl_init_ctx(void)
-{
- static const EGLint ctx_att_gl[] = {
- EGL_NONE
- };
- static const EGLint ctx_att_gles[] = {
- EGL_CONTEXT_CLIENT_VERSION, 2,
- EGL_NONE
- };
-
- EGLContext ectx;
- EGLBoolean b;
-
- egl_dbg("eglCreateContext ...\n");
- ectx = eglCreateContext(qemu_egl_display, qemu_egl_config, EGL_NO_CONTEXT,
- egl_gles ? ctx_att_gles : ctx_att_gl);
- if (ectx == EGL_NO_CONTEXT) {
- fprintf(stderr, "egl: eglCreateContext failed\n");
- return NULL;
- }
-
- b = eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, ectx);
- if (b == EGL_FALSE) {
- fprintf(stderr, "egl: eglMakeCurrent failed\n");
- return NULL;
- }
-
- return ectx;
-}
diff --git a/qemu/ui/gtk-egl.c b/qemu/ui/gtk-egl.c
deleted file mode 100644
index 431457c74..000000000
--- a/qemu/ui/gtk-egl.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * GTK UI -- egl opengl code.
- *
- * Note that gtk 3.16+ (released 2015-03-23) has a GtkGLArea widget,
- * which is GtkDrawingArea like widget with opengl rendering support.
- *
- * This code handles opengl support on older gtk versions, using egl
- * to get a opengl context for the X11 window.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-
-#include "trace.h"
-
-#include "ui/console.h"
-#include "ui/gtk.h"
-#include "ui/egl-helpers.h"
-
-#include "sysemu/sysemu.h"
-
-static void gtk_egl_set_scanout_mode(VirtualConsole *vc, bool scanout)
-{
- if (vc->gfx.scanout_mode == scanout) {
- return;
- }
-
- vc->gfx.scanout_mode = scanout;
- if (!vc->gfx.scanout_mode) {
- if (vc->gfx.fbo_id) {
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, 0, 0);
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
- glDeleteFramebuffers(1, &vc->gfx.fbo_id);
- vc->gfx.fbo_id = 0;
- }
- if (vc->gfx.surface) {
- surface_gl_destroy_texture(vc->gfx.gls, vc->gfx.ds);
- surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
- }
- }
-}
-
-/** DisplayState Callbacks (opengl version) **/
-
-void gd_egl_init(VirtualConsole *vc)
-{
- GdkWindow *gdk_window = gtk_widget_get_window(vc->gfx.drawing_area);
- if (!gdk_window) {
- return;
- }
-
-#if GTK_CHECK_VERSION(3, 0, 0)
- Window x11_window = gdk_x11_window_get_xid(gdk_window);
-#else
- Window x11_window = gdk_x11_drawable_get_xid(gdk_window);
-#endif
- if (!x11_window) {
- return;
- }
-
- vc->gfx.ectx = qemu_egl_init_ctx();
- vc->gfx.esurface = qemu_egl_init_surface_x11(vc->gfx.ectx, x11_window);
-
- assert(vc->gfx.esurface);
-}
-
-void gd_egl_draw(VirtualConsole *vc)
-{
- GdkWindow *window;
- int ww, wh;
-
- if (!vc->gfx.gls) {
- return;
- }
-
- if (vc->gfx.scanout_mode) {
- gd_egl_scanout_flush(&vc->gfx.dcl, 0, 0, vc->gfx.w, vc->gfx.h);
- } else {
- if (!vc->gfx.ds) {
- return;
- }
- eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
- vc->gfx.esurface, vc->gfx.ectx);
-
- window = gtk_widget_get_window(vc->gfx.drawing_area);
- gdk_drawable_get_size(window, &ww, &wh);
- surface_gl_setup_viewport(vc->gfx.gls, vc->gfx.ds, ww, wh);
- surface_gl_render_texture(vc->gfx.gls, vc->gfx.ds);
-
- eglSwapBuffers(qemu_egl_display, vc->gfx.esurface);
- }
-}
-
-void gd_egl_update(DisplayChangeListener *dcl,
- int x, int y, int w, int h)
-{
- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
-
- if (!vc->gfx.gls || !vc->gfx.ds) {
- return;
- }
-
- eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
- vc->gfx.esurface, vc->gfx.ectx);
- surface_gl_update_texture(vc->gfx.gls, vc->gfx.ds, x, y, w, h);
- vc->gfx.glupdates++;
-}
-
-void gd_egl_refresh(DisplayChangeListener *dcl)
-{
- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
-
- if (!vc->gfx.esurface) {
- gd_egl_init(vc);
- if (!vc->gfx.esurface) {
- return;
- }
- vc->gfx.gls = console_gl_init_context();
- if (vc->gfx.ds) {
- surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
- }
- }
-
- graphic_hw_update(dcl->con);
-
- if (vc->gfx.glupdates) {
- vc->gfx.glupdates = 0;
- gtk_egl_set_scanout_mode(vc, false);
- gd_egl_draw(vc);
- }
-}
-
-void gd_egl_switch(DisplayChangeListener *dcl,
- DisplaySurface *surface)
-{
- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
- bool resized = true;
-
- trace_gd_switch(vc->label, surface_width(surface), surface_height(surface));
-
- if (vc->gfx.ds &&
- surface_width(vc->gfx.ds) == surface_width(surface) &&
- surface_height(vc->gfx.ds) == surface_height(surface)) {
- resized = false;
- }
-
- surface_gl_destroy_texture(vc->gfx.gls, vc->gfx.ds);
- vc->gfx.ds = surface;
- if (vc->gfx.gls) {
- surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
- }
-
- if (resized) {
- gd_update_windowsize(vc);
- }
-}
-
-QEMUGLContext gd_egl_create_context(DisplayChangeListener *dcl,
- QEMUGLParams *params)
-{
- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
-
- eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
- vc->gfx.esurface, vc->gfx.ectx);
- return qemu_egl_create_context(dcl, params);
-}
-
-void gd_egl_scanout(DisplayChangeListener *dcl,
- uint32_t backing_id, bool backing_y_0_top,
- uint32_t x, uint32_t y,
- uint32_t w, uint32_t h)
-{
- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
-
- vc->gfx.x = x;
- vc->gfx.y = y;
- vc->gfx.w = w;
- vc->gfx.h = h;
- vc->gfx.tex_id = backing_id;
- vc->gfx.y0_top = backing_y_0_top;
-
- eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
- vc->gfx.esurface, vc->gfx.ectx);
-
- if (vc->gfx.tex_id == 0 || vc->gfx.w == 0 || vc->gfx.h == 0) {
- gtk_egl_set_scanout_mode(vc, false);
- return;
- }
-
- gtk_egl_set_scanout_mode(vc, true);
- if (!vc->gfx.fbo_id) {
- glGenFramebuffers(1, &vc->gfx.fbo_id);
- }
-
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, vc->gfx.fbo_id);
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, vc->gfx.tex_id, 0);
-}
-
-void gd_egl_scanout_flush(DisplayChangeListener *dcl,
- uint32_t x, uint32_t y, uint32_t w, uint32_t h)
-{
- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
- GdkWindow *window;
- int ww, wh, y1, y2;
-
- if (!vc->gfx.scanout_mode) {
- return;
- }
- if (!vc->gfx.fbo_id) {
- return;
- }
-
- eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
- vc->gfx.esurface, vc->gfx.ectx);
-
- glBindFramebuffer(GL_READ_FRAMEBUFFER, vc->gfx.fbo_id);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
-
- window = gtk_widget_get_window(vc->gfx.drawing_area);
- gdk_drawable_get_size(window, &ww, &wh);
- glViewport(0, 0, ww, wh);
- y1 = vc->gfx.y0_top ? 0 : vc->gfx.h;
- y2 = vc->gfx.y0_top ? vc->gfx.h : 0;
- glBlitFramebuffer(0, y1, vc->gfx.w, y2,
- 0, 0, ww, wh,
- GL_COLOR_BUFFER_BIT, GL_NEAREST);
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, vc->gfx.fbo_id);
-
- eglSwapBuffers(qemu_egl_display, vc->gfx.esurface);
-}
-
-void gtk_egl_init(void)
-{
- GdkDisplay *gdk_display = gdk_display_get_default();
- Display *x11_display = gdk_x11_display_get_xdisplay(gdk_display);
-
- if (qemu_egl_init_dpy(x11_display, false, false) < 0) {
- return;
- }
-
- display_opengl = 1;
-}
-
-int gd_egl_make_current(DisplayChangeListener *dcl,
- QEMUGLContext ctx)
-{
- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
-
- return eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
- vc->gfx.esurface, ctx);
-}
diff --git a/qemu/ui/gtk-gl-area.c b/qemu/ui/gtk-gl-area.c
deleted file mode 100644
index b86ff3cbe..000000000
--- a/qemu/ui/gtk-gl-area.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * GTK UI -- glarea opengl code.
- *
- * Requires 3.16+ (GtkGLArea widget).
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-
-#include "trace.h"
-
-#include "ui/console.h"
-#include "ui/gtk.h"
-#include "ui/egl-helpers.h"
-
-#include "sysemu/sysemu.h"
-
-static void gtk_gl_area_set_scanout_mode(VirtualConsole *vc, bool scanout)
-{
- if (vc->gfx.scanout_mode == scanout) {
- return;
- }
-
- vc->gfx.scanout_mode = scanout;
- if (!vc->gfx.scanout_mode) {
- if (vc->gfx.fbo_id) {
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, 0, 0);
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
- glDeleteFramebuffers(1, &vc->gfx.fbo_id);
- vc->gfx.fbo_id = 0;
- }
- if (vc->gfx.surface) {
- surface_gl_destroy_texture(vc->gfx.gls, vc->gfx.ds);
- surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
- }
- }
-}
-
-/** DisplayState Callbacks (opengl version) **/
-
-void gd_gl_area_draw(VirtualConsole *vc)
-{
- int ww, wh, y1, y2;
-
- if (!vc->gfx.gls) {
- return;
- }
-
- gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
- ww = gtk_widget_get_allocated_width(vc->gfx.drawing_area);
- wh = gtk_widget_get_allocated_height(vc->gfx.drawing_area);
-
- if (vc->gfx.scanout_mode) {
- if (!vc->gfx.fbo_id) {
- return;
- }
-
- glBindFramebuffer(GL_READ_FRAMEBUFFER, vc->gfx.fbo_id);
- /* GtkGLArea sets GL_DRAW_FRAMEBUFFER for us */
-
- glViewport(0, 0, ww, wh);
- y1 = vc->gfx.y0_top ? 0 : vc->gfx.h;
- y2 = vc->gfx.y0_top ? vc->gfx.h : 0;
- glBlitFramebuffer(0, y1, vc->gfx.w, y2,
- 0, 0, ww, wh,
- GL_COLOR_BUFFER_BIT, GL_NEAREST);
- } else {
- if (!vc->gfx.ds) {
- return;
- }
- gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
-
- surface_gl_setup_viewport(vc->gfx.gls, vc->gfx.ds, ww, wh);
- surface_gl_render_texture(vc->gfx.gls, vc->gfx.ds);
- }
-}
-
-void gd_gl_area_update(DisplayChangeListener *dcl,
- int x, int y, int w, int h)
-{
- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
-
- if (!vc->gfx.gls || !vc->gfx.ds) {
- return;
- }
-
- gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
- surface_gl_update_texture(vc->gfx.gls, vc->gfx.ds, x, y, w, h);
- vc->gfx.glupdates++;
-}
-
-void gd_gl_area_refresh(DisplayChangeListener *dcl)
-{
- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
-
- if (!vc->gfx.gls) {
- if (!gtk_widget_get_realized(vc->gfx.drawing_area)) {
- return;
- }
- gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
- vc->gfx.gls = console_gl_init_context();
- if (vc->gfx.ds) {
- surface_gl_create_texture(vc->gfx.gls, vc->gfx.ds);
- }
- }
-
- graphic_hw_update(dcl->con);
-
- if (vc->gfx.glupdates) {
- vc->gfx.glupdates = 0;
- gtk_gl_area_set_scanout_mode(vc, false);
- gtk_gl_area_queue_render(GTK_GL_AREA(vc->gfx.drawing_area));
- }
-}
-
-void gd_gl_area_switch(DisplayChangeListener *dcl,
- DisplaySurface *surface)
-{
- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
- bool resized = true;
-
- trace_gd_switch(vc->label, surface_width(surface), surface_height(surface));
-
- if (vc->gfx.ds &&
- surface_width(vc->gfx.ds) == surface_width(surface) &&
- surface_height(vc->gfx.ds) == surface_height(surface)) {
- resized = false;
- }
-
- if (vc->gfx.gls) {
- gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
- surface_gl_destroy_texture(vc->gfx.gls, vc->gfx.ds);
- surface_gl_create_texture(vc->gfx.gls, surface);
- }
- vc->gfx.ds = surface;
-
- if (resized) {
- gd_update_windowsize(vc);
- }
-}
-
-QEMUGLContext gd_gl_area_create_context(DisplayChangeListener *dcl,
- QEMUGLParams *params)
-{
- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
- GdkWindow *window;
- GdkGLContext *ctx;
- GError *err = NULL;
-
- gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
- window = gtk_widget_get_window(vc->gfx.drawing_area);
- ctx = gdk_window_create_gl_context(window, &err);
- gdk_gl_context_set_required_version(ctx,
- params->major_ver,
- params->minor_ver);
- gdk_gl_context_realize(ctx, &err);
- return ctx;
-}
-
-void gd_gl_area_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx)
-{
- /* FIXME */
-}
-
-void gd_gl_area_scanout(DisplayChangeListener *dcl,
- uint32_t backing_id, bool backing_y_0_top,
- uint32_t x, uint32_t y,
- uint32_t w, uint32_t h)
-{
- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
-
- vc->gfx.x = x;
- vc->gfx.y = y;
- vc->gfx.w = w;
- vc->gfx.h = h;
- vc->gfx.tex_id = backing_id;
- vc->gfx.y0_top = backing_y_0_top;
-
- gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
-
- if (vc->gfx.tex_id == 0 || vc->gfx.w == 0 || vc->gfx.h == 0) {
- gtk_gl_area_set_scanout_mode(vc, false);
- return;
- }
-
- gtk_gl_area_set_scanout_mode(vc, true);
- if (!vc->gfx.fbo_id) {
- glGenFramebuffers(1, &vc->gfx.fbo_id);
- }
-
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, vc->gfx.fbo_id);
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, vc->gfx.tex_id, 0);
-}
-
-void gd_gl_area_scanout_flush(DisplayChangeListener *dcl,
- uint32_t x, uint32_t y, uint32_t w, uint32_t h)
-{
- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
-
- gtk_gl_area_queue_render(GTK_GL_AREA(vc->gfx.drawing_area));
-}
-
-void gtk_gl_area_init(void)
-{
- display_opengl = 1;
-}
-
-QEMUGLContext gd_gl_area_get_current_context(DisplayChangeListener *dcl)
-{
- return gdk_gl_context_get_current();
-}
-
-int gd_gl_area_make_current(DisplayChangeListener *dcl,
- QEMUGLContext ctx)
-{
- gdk_gl_context_make_current(ctx);
- return 0;
-}
diff --git a/qemu/ui/gtk.c b/qemu/ui/gtk.c
deleted file mode 100644
index f372a6d5a..000000000
--- a/qemu/ui/gtk.c
+++ /dev/null
@@ -1,2212 +0,0 @@
-/*
- * GTK UI
- *
- * Copyright IBM, Corp. 2012
- *
- * Authors:
- * Anthony Liguori <aliguori@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- * Portions from gtk-vnc:
- *
- * GTK VNC Widget
- *
- * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
- * Copyright (C) 2009-2010 Daniel P. Berrange <dan@berrange.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.0 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#define GETTEXT_PACKAGE "qemu"
-#define LOCALEDIR "po"
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "qemu/cutils.h"
-
-#include "ui/console.h"
-#include "ui/gtk.h"
-
-#include <glib/gi18n.h>
-#include <locale.h>
-#if defined(CONFIG_VTE)
-#include <vte/vte.h>
-#endif
-#include <math.h>
-
-#include "trace.h"
-#include "ui/input.h"
-#include "sysemu/sysemu.h"
-#include "qmp-commands.h"
-#include "x_keymap.h"
-#include "keymaps.h"
-#include "sysemu/char.h"
-#include "qom/object.h"
-
-#define MAX_VCS 10
-#define VC_WINDOW_X_MIN 320
-#define VC_WINDOW_Y_MIN 240
-#define VC_TERM_X_MIN 80
-#define VC_TERM_Y_MIN 25
-#define VC_SCALE_MIN 0.25
-#define VC_SCALE_STEP 0.25
-
-#if !defined(CONFIG_VTE)
-# define VTE_CHECK_VERSION(a, b, c) 0
-#endif
-
-#if defined(CONFIG_VTE) && !GTK_CHECK_VERSION(3, 0, 0)
-/*
- * The gtk2 vte terminal widget seriously messes up the window resize
- * for some reason. You basically can't make the qemu window smaller
- * any more because the toplevel window geoemtry hints are overridden.
- *
- * Workaround that by hiding all vte widgets, except the one in the
- * current tab.
- *
- * Luckily everything works smooth in gtk3.
- */
-# define VTE_RESIZE_HACK 1
-#endif
-
-#if !GTK_CHECK_VERSION(2, 20, 0)
-#define gtk_widget_get_realized(widget) GTK_WIDGET_REALIZED(widget)
-#endif
-
-#ifndef GDK_IS_X11_DISPLAY
-#define GDK_IS_X11_DISPLAY(dpy) (dpy == dpy)
-#endif
-#ifndef GDK_IS_WIN32_DISPLAY
-#define GDK_IS_WIN32_DISPLAY(dpy) (dpy == dpy)
-#endif
-
-#ifndef GDK_KEY_0
-#define GDK_KEY_0 GDK_0
-#define GDK_KEY_1 GDK_1
-#define GDK_KEY_2 GDK_2
-#define GDK_KEY_f GDK_f
-#define GDK_KEY_g GDK_g
-#define GDK_KEY_q GDK_q
-#define GDK_KEY_plus GDK_plus
-#define GDK_KEY_minus GDK_minus
-#define GDK_KEY_Pause GDK_Pause
-#endif
-
-/* Some older mingw versions lack this constant or have
- * it conditionally defined */
-#ifdef _WIN32
-# ifndef MAPVK_VK_TO_VSC
-# define MAPVK_VK_TO_VSC 0
-# endif
-#endif
-
-
-#define HOTKEY_MODIFIERS (GDK_CONTROL_MASK | GDK_MOD1_MASK)
-
-static const int modifier_keycode[] = {
- /* shift, control, alt keys, meta keys, both left & right */
- 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8, 0xdb, 0xdd,
-};
-
-struct GtkDisplayState {
- GtkWidget *window;
-
- GtkWidget *menu_bar;
-
- GtkAccelGroup *accel_group;
-
- GtkWidget *machine_menu_item;
- GtkWidget *machine_menu;
- GtkWidget *pause_item;
- GtkWidget *reset_item;
- GtkWidget *powerdown_item;
- GtkWidget *quit_item;
-
- GtkWidget *view_menu_item;
- GtkWidget *view_menu;
- GtkWidget *full_screen_item;
- GtkWidget *zoom_in_item;
- GtkWidget *zoom_out_item;
- GtkWidget *zoom_fixed_item;
- GtkWidget *zoom_fit_item;
- GtkWidget *grab_item;
- GtkWidget *grab_on_hover_item;
-
- int nb_vcs;
- VirtualConsole vc[MAX_VCS];
-
- GtkWidget *show_tabs_item;
- GtkWidget *untabify_item;
-
- GtkWidget *vbox;
- GtkWidget *notebook;
- int button_mask;
- gboolean last_set;
- int last_x;
- int last_y;
- int grab_x_root;
- int grab_y_root;
- VirtualConsole *kbd_owner;
- VirtualConsole *ptr_owner;
-
- gboolean full_screen;
-
- GdkCursor *null_cursor;
- Notifier mouse_mode_notifier;
- gboolean free_scale;
-
- bool external_pause_update;
-
- bool modifier_pressed[ARRAY_SIZE(modifier_keycode)];
- bool has_evdev;
- bool ignore_keys;
-};
-
-static void gd_grab_pointer(VirtualConsole *vc, const char *reason);
-static void gd_ungrab_pointer(GtkDisplayState *s);
-static void gd_grab_keyboard(VirtualConsole *vc, const char *reason);
-static void gd_ungrab_keyboard(GtkDisplayState *s);
-
-/** Utility Functions **/
-
-static VirtualConsole *gd_vc_find_by_menu(GtkDisplayState *s)
-{
- VirtualConsole *vc;
- gint i;
-
- for (i = 0; i < s->nb_vcs; i++) {
- vc = &s->vc[i];
- if (gtk_check_menu_item_get_active
- (GTK_CHECK_MENU_ITEM(vc->menu_item))) {
- return vc;
- }
- }
- return NULL;
-}
-
-static VirtualConsole *gd_vc_find_by_page(GtkDisplayState *s, gint page)
-{
- VirtualConsole *vc;
- gint i, p;
-
- for (i = 0; i < s->nb_vcs; i++) {
- vc = &s->vc[i];
- p = gtk_notebook_page_num(GTK_NOTEBOOK(s->notebook), vc->tab_item);
- if (p == page) {
- return vc;
- }
- }
- return NULL;
-}
-
-static VirtualConsole *gd_vc_find_current(GtkDisplayState *s)
-{
- gint page;
-
- page = gtk_notebook_get_current_page(GTK_NOTEBOOK(s->notebook));
- return gd_vc_find_by_page(s, page);
-}
-
-static bool gd_is_grab_active(GtkDisplayState *s)
-{
- return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(s->grab_item));
-}
-
-static bool gd_grab_on_hover(GtkDisplayState *s)
-{
- return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(s->grab_on_hover_item));
-}
-
-static void gd_update_cursor(VirtualConsole *vc)
-{
- GtkDisplayState *s = vc->s;
- GdkWindow *window;
-
- if (vc->type != GD_VC_GFX ||
- !qemu_console_is_graphic(vc->gfx.dcl.con)) {
- return;
- }
-
- if (!gtk_widget_get_realized(vc->gfx.drawing_area)) {
- return;
- }
-
- window = gtk_widget_get_window(GTK_WIDGET(vc->gfx.drawing_area));
- if (s->full_screen || qemu_input_is_absolute() || s->ptr_owner == vc) {
- gdk_window_set_cursor(window, s->null_cursor);
- } else {
- gdk_window_set_cursor(window, NULL);
- }
-}
-
-static void gd_update_caption(GtkDisplayState *s)
-{
- const char *status = "";
- gchar *prefix;
- gchar *title;
- const char *grab = "";
- bool is_paused = !runstate_is_running();
- int i;
-
- if (qemu_name) {
- prefix = g_strdup_printf("QEMU (%s)", qemu_name);
- } else {
- prefix = g_strdup_printf("QEMU");
- }
-
- if (s->ptr_owner != NULL &&
- s->ptr_owner->window == NULL) {
- grab = _(" - Press Ctrl+Alt+G to release grab");
- }
-
- if (is_paused) {
- status = _(" [Paused]");
- }
- s->external_pause_update = true;
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->pause_item),
- is_paused);
- s->external_pause_update = false;
-
- title = g_strdup_printf("%s%s%s", prefix, status, grab);
- gtk_window_set_title(GTK_WINDOW(s->window), title);
- g_free(title);
-
- for (i = 0; i < s->nb_vcs; i++) {
- VirtualConsole *vc = &s->vc[i];
-
- if (!vc->window) {
- continue;
- }
- title = g_strdup_printf("%s: %s%s%s", prefix, vc->label,
- vc == s->kbd_owner ? " +kbd" : "",
- vc == s->ptr_owner ? " +ptr" : "");
- gtk_window_set_title(GTK_WINDOW(vc->window), title);
- g_free(title);
- }
-
- g_free(prefix);
-}
-
-static void gd_update_geometry_hints(VirtualConsole *vc)
-{
- GtkDisplayState *s = vc->s;
- GdkWindowHints mask = 0;
- GdkGeometry geo = {};
- GtkWidget *geo_widget = NULL;
- GtkWindow *geo_window;
-
- if (vc->type == GD_VC_GFX) {
- if (!vc->gfx.ds) {
- return;
- }
- if (s->free_scale) {
- geo.min_width = surface_width(vc->gfx.ds) * VC_SCALE_MIN;
- geo.min_height = surface_height(vc->gfx.ds) * VC_SCALE_MIN;
- mask |= GDK_HINT_MIN_SIZE;
- } else {
- geo.min_width = surface_width(vc->gfx.ds) * vc->gfx.scale_x;
- geo.min_height = surface_height(vc->gfx.ds) * vc->gfx.scale_y;
- mask |= GDK_HINT_MIN_SIZE;
- }
- geo_widget = vc->gfx.drawing_area;
- gtk_widget_set_size_request(geo_widget, geo.min_width, geo.min_height);
-
-#if defined(CONFIG_VTE)
- } else if (vc->type == GD_VC_VTE) {
- VteTerminal *term = VTE_TERMINAL(vc->vte.terminal);
- GtkBorder *ib;
-
- geo.width_inc = vte_terminal_get_char_width(term);
- geo.height_inc = vte_terminal_get_char_height(term);
- mask |= GDK_HINT_RESIZE_INC;
- geo.base_width = geo.width_inc;
- geo.base_height = geo.height_inc;
- mask |= GDK_HINT_BASE_SIZE;
- geo.min_width = geo.width_inc * VC_TERM_X_MIN;
- geo.min_height = geo.height_inc * VC_TERM_Y_MIN;
- mask |= GDK_HINT_MIN_SIZE;
- gtk_widget_style_get(vc->vte.terminal, "inner-border", &ib, NULL);
- geo.base_width += ib->left + ib->right;
- geo.base_height += ib->top + ib->bottom;
- geo.min_width += ib->left + ib->right;
- geo.min_height += ib->top + ib->bottom;
- geo_widget = vc->vte.terminal;
-#endif
- }
-
- geo_window = GTK_WINDOW(vc->window ? vc->window : s->window);
- gtk_window_set_geometry_hints(geo_window, geo_widget, &geo, mask);
-}
-
-void gd_update_windowsize(VirtualConsole *vc)
-{
- GtkDisplayState *s = vc->s;
-
- gd_update_geometry_hints(vc);
-
- if (vc->type == GD_VC_GFX && !s->full_screen && !s->free_scale) {
- gtk_window_resize(GTK_WINDOW(vc->window ? vc->window : s->window),
- VC_WINDOW_X_MIN, VC_WINDOW_Y_MIN);
- }
-}
-
-static void gd_update_full_redraw(VirtualConsole *vc)
-{
- GtkWidget *area = vc->gfx.drawing_area;
- int ww, wh;
- gdk_drawable_get_size(gtk_widget_get_window(area), &ww, &wh);
-#if defined(CONFIG_GTK_GL)
- if (vc->gfx.gls) {
- gtk_gl_area_queue_render(GTK_GL_AREA(vc->gfx.drawing_area));
- return;
- }
-#endif
- gtk_widget_queue_draw_area(area, 0, 0, ww, wh);
-}
-
-static void gtk_release_modifiers(GtkDisplayState *s)
-{
- VirtualConsole *vc = gd_vc_find_current(s);
- int i, keycode;
-
- if (vc->type != GD_VC_GFX ||
- !qemu_console_is_graphic(vc->gfx.dcl.con)) {
- return;
- }
- for (i = 0; i < ARRAY_SIZE(modifier_keycode); i++) {
- keycode = modifier_keycode[i];
- if (!s->modifier_pressed[i]) {
- continue;
- }
- qemu_input_event_send_key_number(vc->gfx.dcl.con, keycode, false);
- s->modifier_pressed[i] = false;
- }
-}
-
-static void gd_widget_reparent(GtkWidget *from, GtkWidget *to,
- GtkWidget *widget)
-{
- g_object_ref(G_OBJECT(widget));
- gtk_container_remove(GTK_CONTAINER(from), widget);
- gtk_container_add(GTK_CONTAINER(to), widget);
- g_object_unref(G_OBJECT(widget));
-}
-
-/** DisplayState Callbacks **/
-
-static void gd_update(DisplayChangeListener *dcl,
- int x, int y, int w, int h)
-{
- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
- GdkWindow *win;
- int x1, x2, y1, y2;
- int mx, my;
- int fbw, fbh;
- int ww, wh;
-
- trace_gd_update(vc->label, x, y, w, h);
-
- if (!gtk_widget_get_realized(vc->gfx.drawing_area)) {
- return;
- }
-
- if (vc->gfx.convert) {
- pixman_image_composite(PIXMAN_OP_SRC, vc->gfx.ds->image,
- NULL, vc->gfx.convert,
- x, y, 0, 0, x, y, w, h);
- }
-
- x1 = floor(x * vc->gfx.scale_x);
- y1 = floor(y * vc->gfx.scale_y);
-
- x2 = ceil(x * vc->gfx.scale_x + w * vc->gfx.scale_x);
- y2 = ceil(y * vc->gfx.scale_y + h * vc->gfx.scale_y);
-
- fbw = surface_width(vc->gfx.ds) * vc->gfx.scale_x;
- fbh = surface_height(vc->gfx.ds) * vc->gfx.scale_y;
-
- win = gtk_widget_get_window(vc->gfx.drawing_area);
- if (!win) {
- return;
- }
- gdk_drawable_get_size(win, &ww, &wh);
-
- mx = my = 0;
- if (ww > fbw) {
- mx = (ww - fbw) / 2;
- }
- if (wh > fbh) {
- my = (wh - fbh) / 2;
- }
-
- gtk_widget_queue_draw_area(vc->gfx.drawing_area,
- mx + x1, my + y1, (x2 - x1), (y2 - y1));
-}
-
-static void gd_refresh(DisplayChangeListener *dcl)
-{
- graphic_hw_update(dcl->con);
-}
-
-#if GTK_CHECK_VERSION(3, 0, 0)
-static void gd_mouse_set(DisplayChangeListener *dcl,
- int x, int y, int visible)
-{
- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
- GdkDisplay *dpy;
- GdkDeviceManager *mgr;
- gint x_root, y_root;
-
- if (qemu_input_is_absolute()) {
- return;
- }
-
- dpy = gtk_widget_get_display(vc->gfx.drawing_area);
- mgr = gdk_display_get_device_manager(dpy);
- gdk_window_get_root_coords(gtk_widget_get_window(vc->gfx.drawing_area),
- x, y, &x_root, &y_root);
- gdk_device_warp(gdk_device_manager_get_client_pointer(mgr),
- gtk_widget_get_screen(vc->gfx.drawing_area),
- x_root, y_root);
- vc->s->last_x = x;
- vc->s->last_y = y;
-}
-#else
-static void gd_mouse_set(DisplayChangeListener *dcl,
- int x, int y, int visible)
-{
- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
- gint x_root, y_root;
-
- if (qemu_input_is_absolute()) {
- return;
- }
-
- gdk_window_get_root_coords(gtk_widget_get_window(vc->gfx.drawing_area),
- x, y, &x_root, &y_root);
- gdk_display_warp_pointer(gtk_widget_get_display(vc->gfx.drawing_area),
- gtk_widget_get_screen(vc->gfx.drawing_area),
- x_root, y_root);
-}
-#endif
-
-static void gd_cursor_define(DisplayChangeListener *dcl,
- QEMUCursor *c)
-{
- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
- GdkPixbuf *pixbuf;
- GdkCursor *cursor;
-
- if (!gtk_widget_get_realized(vc->gfx.drawing_area)) {
- return;
- }
-
- pixbuf = gdk_pixbuf_new_from_data((guchar *)(c->data),
- GDK_COLORSPACE_RGB, true, 8,
- c->width, c->height, c->width * 4,
- NULL, NULL);
- cursor = gdk_cursor_new_from_pixbuf
- (gtk_widget_get_display(vc->gfx.drawing_area),
- pixbuf, c->hot_x, c->hot_y);
- gdk_window_set_cursor(gtk_widget_get_window(vc->gfx.drawing_area), cursor);
- g_object_unref(pixbuf);
-#if !GTK_CHECK_VERSION(3, 0, 0)
- gdk_cursor_unref(cursor);
-#else
- g_object_unref(cursor);
-#endif
-}
-
-static void gd_switch(DisplayChangeListener *dcl,
- DisplaySurface *surface)
-{
- VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
- bool resized = true;
-
- trace_gd_switch(vc->label,
- surface ? surface_width(surface) : 0,
- surface ? surface_height(surface) : 0);
-
- if (vc->gfx.surface) {
- cairo_surface_destroy(vc->gfx.surface);
- vc->gfx.surface = NULL;
- }
- if (vc->gfx.convert) {
- pixman_image_unref(vc->gfx.convert);
- vc->gfx.convert = NULL;
- }
-
- if (vc->gfx.ds && surface &&
- surface_width(vc->gfx.ds) == surface_width(surface) &&
- surface_height(vc->gfx.ds) == surface_height(surface)) {
- resized = false;
- }
- vc->gfx.ds = surface;
-
- if (!surface) {
- return;
- }
-
- if (surface->format == PIXMAN_x8r8g8b8) {
- /*
- * PIXMAN_x8r8g8b8 == CAIRO_FORMAT_RGB24
- *
- * No need to convert, use surface directly. Should be the
- * common case as this is qemu_default_pixelformat(32) too.
- */
- vc->gfx.surface = cairo_image_surface_create_for_data
- (surface_data(surface),
- CAIRO_FORMAT_RGB24,
- surface_width(surface),
- surface_height(surface),
- surface_stride(surface));
- } else {
- /* Must convert surface, use pixman to do it. */
- vc->gfx.convert = pixman_image_create_bits(PIXMAN_x8r8g8b8,
- surface_width(surface),
- surface_height(surface),
- NULL, 0);
- vc->gfx.surface = cairo_image_surface_create_for_data
- ((void *)pixman_image_get_data(vc->gfx.convert),
- CAIRO_FORMAT_RGB24,
- pixman_image_get_width(vc->gfx.convert),
- pixman_image_get_height(vc->gfx.convert),
- pixman_image_get_stride(vc->gfx.convert));
- pixman_image_composite(PIXMAN_OP_SRC, vc->gfx.ds->image,
- NULL, vc->gfx.convert,
- 0, 0, 0, 0, 0, 0,
- pixman_image_get_width(vc->gfx.convert),
- pixman_image_get_height(vc->gfx.convert));
- }
-
- if (resized) {
- gd_update_windowsize(vc);
- } else {
- gd_update_full_redraw(vc);
- }
-}
-
-static const DisplayChangeListenerOps dcl_ops = {
- .dpy_name = "gtk",
- .dpy_gfx_update = gd_update,
- .dpy_gfx_switch = gd_switch,
- .dpy_gfx_check_format = qemu_pixman_check_format,
- .dpy_refresh = gd_refresh,
- .dpy_mouse_set = gd_mouse_set,
- .dpy_cursor_define = gd_cursor_define,
-};
-
-
-#if defined(CONFIG_OPENGL)
-
-/** DisplayState Callbacks (opengl version) **/
-
-#if defined(CONFIG_GTK_GL)
-
-static const DisplayChangeListenerOps dcl_gl_area_ops = {
- .dpy_name = "gtk-egl",
- .dpy_gfx_update = gd_gl_area_update,
- .dpy_gfx_switch = gd_gl_area_switch,
- .dpy_gfx_check_format = console_gl_check_format,
- .dpy_refresh = gd_gl_area_refresh,
- .dpy_mouse_set = gd_mouse_set,
- .dpy_cursor_define = gd_cursor_define,
-
- .dpy_gl_ctx_create = gd_gl_area_create_context,
- .dpy_gl_ctx_destroy = gd_gl_area_destroy_context,
- .dpy_gl_ctx_make_current = gd_gl_area_make_current,
- .dpy_gl_ctx_get_current = gd_gl_area_get_current_context,
- .dpy_gl_scanout = gd_gl_area_scanout,
- .dpy_gl_update = gd_gl_area_scanout_flush,
-};
-
-#else
-
-static const DisplayChangeListenerOps dcl_egl_ops = {
- .dpy_name = "gtk-egl",
- .dpy_gfx_update = gd_egl_update,
- .dpy_gfx_switch = gd_egl_switch,
- .dpy_gfx_check_format = console_gl_check_format,
- .dpy_refresh = gd_egl_refresh,
- .dpy_mouse_set = gd_mouse_set,
- .dpy_cursor_define = gd_cursor_define,
-
- .dpy_gl_ctx_create = gd_egl_create_context,
- .dpy_gl_ctx_destroy = qemu_egl_destroy_context,
- .dpy_gl_ctx_make_current = gd_egl_make_current,
- .dpy_gl_ctx_get_current = qemu_egl_get_current_context,
- .dpy_gl_scanout = gd_egl_scanout,
- .dpy_gl_update = gd_egl_scanout_flush,
-};
-
-#endif /* CONFIG_GTK_GL */
-#endif /* CONFIG_OPENGL */
-
-/** QEMU Events **/
-
-static void gd_change_runstate(void *opaque, int running, RunState state)
-{
- GtkDisplayState *s = opaque;
-
- gd_update_caption(s);
-}
-
-static void gd_mouse_mode_change(Notifier *notify, void *data)
-{
- GtkDisplayState *s;
- int i;
-
- s = container_of(notify, GtkDisplayState, mouse_mode_notifier);
- /* release the grab at switching to absolute mode */
- if (qemu_input_is_absolute() && gd_is_grab_active(s)) {
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item),
- FALSE);
- }
- for (i = 0; i < s->nb_vcs; i++) {
- VirtualConsole *vc = &s->vc[i];
- gd_update_cursor(vc);
- }
-}
-
-/** GTK Events **/
-
-static gboolean gd_window_close(GtkWidget *widget, GdkEvent *event,
- void *opaque)
-{
- GtkDisplayState *s = opaque;
- int i;
-
- if (!no_quit) {
- for (i = 0; i < s->nb_vcs; i++) {
- if (s->vc[i].type != GD_VC_GFX) {
- continue;
- }
- unregister_displaychangelistener(&s->vc[i].gfx.dcl);
- }
- qmp_quit(NULL);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void gd_set_ui_info(VirtualConsole *vc, gint width, gint height)
-{
- QemuUIInfo info;
-
- memset(&info, 0, sizeof(info));
- info.width = width;
- info.height = height;
- dpy_set_ui_info(vc->gfx.dcl.con, &info);
-}
-
-#if defined(CONFIG_GTK_GL)
-
-static gboolean gd_render_event(GtkGLArea *area, GdkGLContext *context,
- void *opaque)
-{
- VirtualConsole *vc = opaque;
-
- if (vc->gfx.gls) {
- gd_gl_area_draw(vc);
- }
- return TRUE;
-}
-
-static void gd_resize_event(GtkGLArea *area,
- gint width, gint height, gpointer *opaque)
-{
- VirtualConsole *vc = (void *)opaque;
-
- gd_set_ui_info(vc, width, height);
-}
-
-#endif
-
-static gboolean gd_draw_event(GtkWidget *widget, cairo_t *cr, void *opaque)
-{
- VirtualConsole *vc = opaque;
- GtkDisplayState *s = vc->s;
- int mx, my;
- int ww, wh;
- int fbw, fbh;
-
-#if defined(CONFIG_OPENGL)
- if (vc->gfx.gls) {
-#if defined(CONFIG_GTK_GL)
- /* invoke render callback please */
- return FALSE;
-#else
- gd_egl_draw(vc);
- return TRUE;
-#endif
- }
-#endif
-
- if (!gtk_widget_get_realized(widget)) {
- return FALSE;
- }
- if (!vc->gfx.ds) {
- return FALSE;
- }
-
- fbw = surface_width(vc->gfx.ds);
- fbh = surface_height(vc->gfx.ds);
-
- gdk_drawable_get_size(gtk_widget_get_window(widget), &ww, &wh);
-
- if (s->full_screen) {
- vc->gfx.scale_x = (double)ww / fbw;
- vc->gfx.scale_y = (double)wh / fbh;
- } else if (s->free_scale) {
- double sx, sy;
-
- sx = (double)ww / fbw;
- sy = (double)wh / fbh;
-
- vc->gfx.scale_x = vc->gfx.scale_y = MIN(sx, sy);
- }
-
- fbw *= vc->gfx.scale_x;
- fbh *= vc->gfx.scale_y;
-
- mx = my = 0;
- if (ww > fbw) {
- mx = (ww - fbw) / 2;
- }
- if (wh > fbh) {
- my = (wh - fbh) / 2;
- }
-
- cairo_rectangle(cr, 0, 0, ww, wh);
-
- /* Optionally cut out the inner area where the pixmap
- will be drawn. This avoids 'flashing' since we're
- not double-buffering. Note we're using the undocumented
- behaviour of drawing the rectangle from right to left
- to cut out the whole */
- cairo_rectangle(cr, mx + fbw, my,
- -1 * fbw, fbh);
- cairo_fill(cr);
-
- cairo_scale(cr, vc->gfx.scale_x, vc->gfx.scale_y);
- cairo_set_source_surface(cr, vc->gfx.surface,
- mx / vc->gfx.scale_x, my / vc->gfx.scale_y);
- cairo_paint(cr);
-
- return TRUE;
-}
-
-#if !GTK_CHECK_VERSION(3, 0, 0)
-static gboolean gd_expose_event(GtkWidget *widget, GdkEventExpose *expose,
- void *opaque)
-{
- cairo_t *cr;
- gboolean ret;
-
- cr = gdk_cairo_create(gtk_widget_get_window(widget));
- cairo_rectangle(cr,
- expose->area.x,
- expose->area.y,
- expose->area.width,
- expose->area.height);
- cairo_clip(cr);
-
- ret = gd_draw_event(widget, cr, opaque);
-
- cairo_destroy(cr);
-
- return ret;
-}
-#endif
-
-static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion,
- void *opaque)
-{
- VirtualConsole *vc = opaque;
- GtkDisplayState *s = vc->s;
- int x, y;
- int mx, my;
- int fbh, fbw;
- int ww, wh;
-
- if (!vc->gfx.ds) {
- return TRUE;
- }
-
- fbw = surface_width(vc->gfx.ds) * vc->gfx.scale_x;
- fbh = surface_height(vc->gfx.ds) * vc->gfx.scale_y;
-
- gdk_drawable_get_size(gtk_widget_get_window(vc->gfx.drawing_area),
- &ww, &wh);
-
- mx = my = 0;
- if (ww > fbw) {
- mx = (ww - fbw) / 2;
- }
- if (wh > fbh) {
- my = (wh - fbh) / 2;
- }
-
- x = (motion->x - mx) / vc->gfx.scale_x;
- y = (motion->y - my) / vc->gfx.scale_y;
-
- if (qemu_input_is_absolute()) {
- if (x < 0 || y < 0 ||
- x >= surface_width(vc->gfx.ds) ||
- y >= surface_height(vc->gfx.ds)) {
- return TRUE;
- }
- qemu_input_queue_abs(vc->gfx.dcl.con, INPUT_AXIS_X, x,
- surface_width(vc->gfx.ds));
- qemu_input_queue_abs(vc->gfx.dcl.con, INPUT_AXIS_Y, y,
- surface_height(vc->gfx.ds));
- qemu_input_event_sync();
- } else if (s->last_set && s->ptr_owner == vc) {
- qemu_input_queue_rel(vc->gfx.dcl.con, INPUT_AXIS_X, x - s->last_x);
- qemu_input_queue_rel(vc->gfx.dcl.con, INPUT_AXIS_Y, y - s->last_y);
- qemu_input_event_sync();
- }
- s->last_x = x;
- s->last_y = y;
- s->last_set = TRUE;
-
- if (!qemu_input_is_absolute() && s->ptr_owner == vc) {
- GdkScreen *screen = gtk_widget_get_screen(vc->gfx.drawing_area);
- int x = (int)motion->x_root;
- int y = (int)motion->y_root;
-
- /* In relative mode check to see if client pointer hit
- * one of the screen edges, and if so move it back by
- * 200 pixels. This is important because the pointer
- * in the server doesn't correspond 1-for-1, and so
- * may still be only half way across the screen. Without
- * this warp, the server pointer would thus appear to hit
- * an invisible wall */
- if (x == 0) {
- x += 200;
- }
- if (y == 0) {
- y += 200;
- }
- if (x == (gdk_screen_get_width(screen) - 1)) {
- x -= 200;
- }
- if (y == (gdk_screen_get_height(screen) - 1)) {
- y -= 200;
- }
-
- if (x != (int)motion->x_root || y != (int)motion->y_root) {
-#if GTK_CHECK_VERSION(3, 0, 0)
- GdkDevice *dev = gdk_event_get_device((GdkEvent *)motion);
- gdk_device_warp(dev, screen, x, y);
-#else
- GdkDisplay *display = gtk_widget_get_display(widget);
- gdk_display_warp_pointer(display, screen, x, y);
-#endif
- s->last_set = FALSE;
- return FALSE;
- }
- }
- return TRUE;
-}
-
-static gboolean gd_button_event(GtkWidget *widget, GdkEventButton *button,
- void *opaque)
-{
- VirtualConsole *vc = opaque;
- GtkDisplayState *s = vc->s;
- InputButton btn;
-
- /* implicitly grab the input at the first click in the relative mode */
- if (button->button == 1 && button->type == GDK_BUTTON_PRESS &&
- !qemu_input_is_absolute() && s->ptr_owner != vc) {
- if (!vc->window) {
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item),
- TRUE);
- } else {
- gd_grab_pointer(vc, "relative-mode-click");
- }
- return TRUE;
- }
-
- if (button->button == 1) {
- btn = INPUT_BUTTON_LEFT;
- } else if (button->button == 2) {
- btn = INPUT_BUTTON_MIDDLE;
- } else if (button->button == 3) {
- btn = INPUT_BUTTON_RIGHT;
- } else {
- return TRUE;
- }
-
- qemu_input_queue_btn(vc->gfx.dcl.con, btn,
- button->type == GDK_BUTTON_PRESS);
- qemu_input_event_sync();
- return TRUE;
-}
-
-static gboolean gd_scroll_event(GtkWidget *widget, GdkEventScroll *scroll,
- void *opaque)
-{
- VirtualConsole *vc = opaque;
- InputButton btn;
-
- if (scroll->direction == GDK_SCROLL_UP) {
- btn = INPUT_BUTTON_WHEEL_UP;
- } else if (scroll->direction == GDK_SCROLL_DOWN) {
- btn = INPUT_BUTTON_WHEEL_DOWN;
- } else {
- return TRUE;
- }
-
- qemu_input_queue_btn(vc->gfx.dcl.con, btn, true);
- qemu_input_event_sync();
- qemu_input_queue_btn(vc->gfx.dcl.con, btn, false);
- qemu_input_event_sync();
- return TRUE;
-}
-
-static int gd_map_keycode(GtkDisplayState *s, GdkDisplay *dpy, int gdk_keycode)
-{
- int qemu_keycode;
-
-#ifdef GDK_WINDOWING_WIN32
- if (GDK_IS_WIN32_DISPLAY(dpy)) {
- qemu_keycode = MapVirtualKey(gdk_keycode, MAPVK_VK_TO_VSC);
- switch (qemu_keycode) {
- case 103: /* alt gr */
- qemu_keycode = 56 | SCANCODE_GREY;
- break;
- }
- return qemu_keycode;
- }
-#endif
-
- if (gdk_keycode < 9) {
- qemu_keycode = 0;
- } else if (gdk_keycode < 97) {
- qemu_keycode = gdk_keycode - 8;
-#ifdef GDK_WINDOWING_X11
- } else if (GDK_IS_X11_DISPLAY(dpy) && gdk_keycode < 158) {
- if (s->has_evdev) {
- qemu_keycode = translate_evdev_keycode(gdk_keycode - 97);
- } else {
- qemu_keycode = translate_xfree86_keycode(gdk_keycode - 97);
- }
-#endif
- } else if (gdk_keycode == 208) { /* Hiragana_Katakana */
- qemu_keycode = 0x70;
- } else if (gdk_keycode == 211) { /* backslash */
- qemu_keycode = 0x73;
- } else {
- qemu_keycode = 0;
- }
-
- return qemu_keycode;
-}
-
-static gboolean gd_text_key_down(GtkWidget *widget,
- GdkEventKey *key, void *opaque)
-{
- VirtualConsole *vc = opaque;
- QemuConsole *con = vc->gfx.dcl.con;
-
- if (key->length) {
- kbd_put_string_console(con, key->string, key->length);
- } else {
- int num = gd_map_keycode(vc->s, gtk_widget_get_display(widget),
- key->hardware_keycode);
- int qcode = qemu_input_key_number_to_qcode(num);
- kbd_put_qcode_console(con, qcode);
- }
- return TRUE;
-}
-
-static gboolean gd_key_event(GtkWidget *widget, GdkEventKey *key, void *opaque)
-{
- VirtualConsole *vc = opaque;
- GtkDisplayState *s = vc->s;
- int gdk_keycode = key->hardware_keycode;
- int qemu_keycode;
- int i;
-
- if (s->ignore_keys) {
- s->ignore_keys = (key->type == GDK_KEY_PRESS);
- return TRUE;
- }
-
- if (key->keyval == GDK_KEY_Pause) {
- qemu_input_event_send_key_qcode(vc->gfx.dcl.con, Q_KEY_CODE_PAUSE,
- key->type == GDK_KEY_PRESS);
- return TRUE;
- }
-
- qemu_keycode = gd_map_keycode(s, gtk_widget_get_display(widget),
- gdk_keycode);
-
- trace_gd_key_event(vc->label, gdk_keycode, qemu_keycode,
- (key->type == GDK_KEY_PRESS) ? "down" : "up");
-
- for (i = 0; i < ARRAY_SIZE(modifier_keycode); i++) {
- if (qemu_keycode == modifier_keycode[i]) {
- s->modifier_pressed[i] = (key->type == GDK_KEY_PRESS);
- }
- }
-
- qemu_input_event_send_key_number(vc->gfx.dcl.con, qemu_keycode,
- key->type == GDK_KEY_PRESS);
-
- return TRUE;
-}
-
-static gboolean gd_event(GtkWidget *widget, GdkEvent *event, void *opaque)
-{
- if (event->type == GDK_MOTION_NOTIFY) {
- return gd_motion_event(widget, &event->motion, opaque);
- }
- return FALSE;
-}
-
-/** Window Menu Actions **/
-
-static void gd_menu_pause(GtkMenuItem *item, void *opaque)
-{
- GtkDisplayState *s = opaque;
-
- if (s->external_pause_update) {
- return;
- }
- if (runstate_is_running()) {
- qmp_stop(NULL);
- } else {
- qmp_cont(NULL);
- }
-}
-
-static void gd_menu_reset(GtkMenuItem *item, void *opaque)
-{
- qmp_system_reset(NULL);
-}
-
-static void gd_menu_powerdown(GtkMenuItem *item, void *opaque)
-{
- qmp_system_powerdown(NULL);
-}
-
-static void gd_menu_quit(GtkMenuItem *item, void *opaque)
-{
- qmp_quit(NULL);
-}
-
-static void gd_menu_switch_vc(GtkMenuItem *item, void *opaque)
-{
- GtkDisplayState *s = opaque;
- VirtualConsole *vc = gd_vc_find_by_menu(s);
- GtkNotebook *nb = GTK_NOTEBOOK(s->notebook);
- gint page;
-
- gtk_release_modifiers(s);
- if (vc) {
- page = gtk_notebook_page_num(nb, vc->tab_item);
- gtk_notebook_set_current_page(nb, page);
- gtk_widget_grab_focus(vc->focus);
- }
- s->ignore_keys = false;
-}
-
-static void gd_accel_switch_vc(void *opaque)
-{
- VirtualConsole *vc = opaque;
-
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(vc->menu_item), TRUE);
-#if !GTK_CHECK_VERSION(3, 0, 0)
- /* GTK2 sends the accel key to the target console - ignore this until */
- vc->s->ignore_keys = true;
-#endif
-}
-
-static void gd_menu_show_tabs(GtkMenuItem *item, void *opaque)
-{
- GtkDisplayState *s = opaque;
- VirtualConsole *vc = gd_vc_find_current(s);
-
- if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(s->show_tabs_item))) {
- gtk_notebook_set_show_tabs(GTK_NOTEBOOK(s->notebook), TRUE);
- } else {
- gtk_notebook_set_show_tabs(GTK_NOTEBOOK(s->notebook), FALSE);
- }
- gd_update_windowsize(vc);
-}
-
-static gboolean gd_tab_window_close(GtkWidget *widget, GdkEvent *event,
- void *opaque)
-{
- VirtualConsole *vc = opaque;
- GtkDisplayState *s = vc->s;
-
- gtk_widget_set_sensitive(vc->menu_item, true);
- gd_widget_reparent(vc->window, s->notebook, vc->tab_item);
- gtk_notebook_set_tab_label_text(GTK_NOTEBOOK(s->notebook),
- vc->tab_item, vc->label);
- gtk_widget_destroy(vc->window);
- vc->window = NULL;
- return TRUE;
-}
-
-static gboolean gd_win_grab(void *opaque)
-{
- VirtualConsole *vc = opaque;
-
- fprintf(stderr, "%s: %s\n", __func__, vc->label);
- if (vc->s->ptr_owner) {
- gd_ungrab_pointer(vc->s);
- } else {
- gd_grab_pointer(vc, "user-request-detached-tab");
- }
- return TRUE;
-}
-
-static void gd_menu_untabify(GtkMenuItem *item, void *opaque)
-{
- GtkDisplayState *s = opaque;
- VirtualConsole *vc = gd_vc_find_current(s);
-
- if (vc->type == GD_VC_GFX &&
- qemu_console_is_graphic(vc->gfx.dcl.con)) {
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item),
- FALSE);
- }
- if (!vc->window) {
- gtk_widget_set_sensitive(vc->menu_item, false);
- vc->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gd_widget_reparent(s->notebook, vc->window, vc->tab_item);
-
- g_signal_connect(vc->window, "delete-event",
- G_CALLBACK(gd_tab_window_close), vc);
- gtk_widget_show_all(vc->window);
-
- if (qemu_console_is_graphic(vc->gfx.dcl.con)) {
- GtkAccelGroup *ag = gtk_accel_group_new();
- gtk_window_add_accel_group(GTK_WINDOW(vc->window), ag);
-
- GClosure *cb = g_cclosure_new_swap(G_CALLBACK(gd_win_grab),
- vc, NULL);
- gtk_accel_group_connect(ag, GDK_KEY_g, HOTKEY_MODIFIERS, 0, cb);
- }
-
- gd_update_geometry_hints(vc);
- gd_update_caption(s);
- }
-}
-
-static void gd_menu_full_screen(GtkMenuItem *item, void *opaque)
-{
- GtkDisplayState *s = opaque;
- VirtualConsole *vc = gd_vc_find_current(s);
-
- if (!s->full_screen) {
- gtk_notebook_set_show_tabs(GTK_NOTEBOOK(s->notebook), FALSE);
- gtk_widget_hide(s->menu_bar);
- if (vc->type == GD_VC_GFX) {
- gtk_widget_set_size_request(vc->gfx.drawing_area, -1, -1);
- }
- gtk_window_fullscreen(GTK_WINDOW(s->window));
- s->full_screen = TRUE;
- } else {
- gtk_window_unfullscreen(GTK_WINDOW(s->window));
- gd_menu_show_tabs(GTK_MENU_ITEM(s->show_tabs_item), s);
- gtk_widget_show(s->menu_bar);
- s->full_screen = FALSE;
- if (vc->type == GD_VC_GFX) {
- vc->gfx.scale_x = 1.0;
- vc->gfx.scale_y = 1.0;
- gd_update_windowsize(vc);
- }
- }
-
- gd_update_cursor(vc);
-}
-
-static void gd_accel_full_screen(void *opaque)
-{
- GtkDisplayState *s = opaque;
- gtk_menu_item_activate(GTK_MENU_ITEM(s->full_screen_item));
-}
-
-static void gd_menu_zoom_in(GtkMenuItem *item, void *opaque)
-{
- GtkDisplayState *s = opaque;
- VirtualConsole *vc = gd_vc_find_current(s);
-
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->zoom_fit_item),
- FALSE);
-
- vc->gfx.scale_x += VC_SCALE_STEP;
- vc->gfx.scale_y += VC_SCALE_STEP;
-
- gd_update_windowsize(vc);
-}
-
-static void gd_menu_zoom_out(GtkMenuItem *item, void *opaque)
-{
- GtkDisplayState *s = opaque;
- VirtualConsole *vc = gd_vc_find_current(s);
-
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->zoom_fit_item),
- FALSE);
-
- vc->gfx.scale_x -= VC_SCALE_STEP;
- vc->gfx.scale_y -= VC_SCALE_STEP;
-
- vc->gfx.scale_x = MAX(vc->gfx.scale_x, VC_SCALE_MIN);
- vc->gfx.scale_y = MAX(vc->gfx.scale_y, VC_SCALE_MIN);
-
- gd_update_windowsize(vc);
-}
-
-static void gd_menu_zoom_fixed(GtkMenuItem *item, void *opaque)
-{
- GtkDisplayState *s = opaque;
- VirtualConsole *vc = gd_vc_find_current(s);
-
- vc->gfx.scale_x = 1.0;
- vc->gfx.scale_y = 1.0;
-
- gd_update_windowsize(vc);
-}
-
-static void gd_menu_zoom_fit(GtkMenuItem *item, void *opaque)
-{
- GtkDisplayState *s = opaque;
- VirtualConsole *vc = gd_vc_find_current(s);
-
- if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(s->zoom_fit_item))) {
- s->free_scale = TRUE;
- } else {
- s->free_scale = FALSE;
- vc->gfx.scale_x = 1.0;
- vc->gfx.scale_y = 1.0;
- }
-
- gd_update_windowsize(vc);
- gd_update_full_redraw(vc);
-}
-
-#if GTK_CHECK_VERSION(3, 0, 0)
-static void gd_grab_devices(VirtualConsole *vc, bool grab,
- GdkInputSource source, GdkEventMask mask,
- GdkCursor *cursor)
-{
- GdkDisplay *display = gtk_widget_get_display(vc->gfx.drawing_area);
- GdkDeviceManager *mgr = gdk_display_get_device_manager(display);
- GList *devs = gdk_device_manager_list_devices(mgr, GDK_DEVICE_TYPE_MASTER);
- GList *tmp = devs;
-
- for (tmp = devs; tmp; tmp = tmp->next) {
- GdkDevice *dev = tmp->data;
- if (gdk_device_get_source(dev) != source) {
- continue;
- }
- if (grab) {
- GdkWindow *win = gtk_widget_get_window(vc->gfx.drawing_area);
- gdk_device_grab(dev, win, GDK_OWNERSHIP_NONE, FALSE,
- mask, cursor, GDK_CURRENT_TIME);
- } else {
- gdk_device_ungrab(dev, GDK_CURRENT_TIME);
- }
- }
- g_list_free(devs);
-}
-#endif
-
-static void gd_grab_keyboard(VirtualConsole *vc, const char *reason)
-{
- if (vc->s->kbd_owner) {
- if (vc->s->kbd_owner == vc) {
- return;
- } else {
- gd_ungrab_keyboard(vc->s);
- }
- }
-
-#if GTK_CHECK_VERSION(3, 0, 0)
- gd_grab_devices(vc, true, GDK_SOURCE_KEYBOARD,
- GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
- NULL);
-#else
- gdk_keyboard_grab(gtk_widget_get_window(vc->gfx.drawing_area),
- FALSE,
- GDK_CURRENT_TIME);
-#endif
- vc->s->kbd_owner = vc;
- gd_update_caption(vc->s);
- trace_gd_grab(vc->label, "kbd", reason);
-}
-
-static void gd_ungrab_keyboard(GtkDisplayState *s)
-{
- VirtualConsole *vc = s->kbd_owner;
-
- if (vc == NULL) {
- return;
- }
- s->kbd_owner = NULL;
-
-#if GTK_CHECK_VERSION(3, 0, 0)
- gd_grab_devices(vc, false, GDK_SOURCE_KEYBOARD, 0, NULL);
-#else
- gdk_keyboard_ungrab(GDK_CURRENT_TIME);
-#endif
- gd_update_caption(s);
- trace_gd_ungrab(vc->label, "kbd");
-}
-
-static void gd_grab_pointer(VirtualConsole *vc, const char *reason)
-{
- GdkDisplay *display = gtk_widget_get_display(vc->gfx.drawing_area);
-
- if (vc->s->ptr_owner) {
- if (vc->s->ptr_owner == vc) {
- return;
- } else {
- gd_ungrab_pointer(vc->s);
- }
- }
-
-#if GTK_CHECK_VERSION(3, 0, 0)
- GdkDeviceManager *mgr = gdk_display_get_device_manager(display);
- gd_grab_devices(vc, true, GDK_SOURCE_MOUSE,
- GDK_POINTER_MOTION_MASK |
- GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK |
- GDK_BUTTON_MOTION_MASK |
- GDK_SCROLL_MASK,
- vc->s->null_cursor);
- gdk_device_get_position(gdk_device_manager_get_client_pointer(mgr),
- NULL, &vc->s->grab_x_root, &vc->s->grab_y_root);
-#else
- gdk_pointer_grab(gtk_widget_get_window(vc->gfx.drawing_area),
- FALSE, /* All events to come to our window directly */
- GDK_POINTER_MOTION_MASK |
- GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK |
- GDK_BUTTON_MOTION_MASK |
- GDK_SCROLL_MASK,
- NULL, /* Allow cursor to move over entire desktop */
- vc->s->null_cursor,
- GDK_CURRENT_TIME);
- gdk_display_get_pointer(display, NULL,
- &vc->s->grab_x_root, &vc->s->grab_y_root, NULL);
-#endif
- vc->s->ptr_owner = vc;
- gd_update_caption(vc->s);
- trace_gd_grab(vc->label, "ptr", reason);
-}
-
-static void gd_ungrab_pointer(GtkDisplayState *s)
-{
- VirtualConsole *vc = s->ptr_owner;
-
- if (vc == NULL) {
- return;
- }
- s->ptr_owner = NULL;
-
- GdkDisplay *display = gtk_widget_get_display(vc->gfx.drawing_area);
-#if GTK_CHECK_VERSION(3, 0, 0)
- GdkDeviceManager *mgr = gdk_display_get_device_manager(display);
- gd_grab_devices(vc, false, GDK_SOURCE_MOUSE, 0, NULL);
- gdk_device_warp(gdk_device_manager_get_client_pointer(mgr),
- gtk_widget_get_screen(vc->gfx.drawing_area),
- vc->s->grab_x_root, vc->s->grab_y_root);
-#else
- gdk_pointer_ungrab(GDK_CURRENT_TIME);
- gdk_display_warp_pointer(display,
- gtk_widget_get_screen(vc->gfx.drawing_area),
- vc->s->grab_x_root, vc->s->grab_y_root);
-#endif
- gd_update_caption(s);
- trace_gd_ungrab(vc->label, "ptr");
-}
-
-static void gd_menu_grab_input(GtkMenuItem *item, void *opaque)
-{
- GtkDisplayState *s = opaque;
- VirtualConsole *vc = gd_vc_find_current(s);
-
- if (gd_is_grab_active(s)) {
- gd_grab_keyboard(vc, "user-request-main-window");
- gd_grab_pointer(vc, "user-request-main-window");
- } else {
- gd_ungrab_keyboard(s);
- gd_ungrab_pointer(s);
- }
-
- gd_update_cursor(vc);
-}
-
-static void gd_change_page(GtkNotebook *nb, gpointer arg1, guint arg2,
- gpointer data)
-{
- GtkDisplayState *s = data;
- VirtualConsole *vc;
- gboolean on_vga;
-
- if (!gtk_widget_get_realized(s->notebook)) {
- return;
- }
-
-#ifdef VTE_RESIZE_HACK
- vc = gd_vc_find_current(s);
- if (vc && vc->type == GD_VC_VTE) {
- gtk_widget_hide(vc->vte.terminal);
- }
-#endif
- vc = gd_vc_find_by_page(s, arg2);
- if (!vc) {
- return;
- }
-#ifdef VTE_RESIZE_HACK
- if (vc->type == GD_VC_VTE) {
- gtk_widget_show(vc->vte.terminal);
- }
-#endif
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(vc->menu_item),
- TRUE);
- on_vga = (vc->type == GD_VC_GFX &&
- qemu_console_is_graphic(vc->gfx.dcl.con));
- if (!on_vga) {
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item),
- FALSE);
- } else if (s->full_screen) {
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item),
- TRUE);
- }
- gtk_widget_set_sensitive(s->grab_item, on_vga);
-
- gd_update_windowsize(vc);
- gd_update_cursor(vc);
-}
-
-static gboolean gd_enter_event(GtkWidget *widget, GdkEventCrossing *crossing,
- gpointer opaque)
-{
- VirtualConsole *vc = opaque;
- GtkDisplayState *s = vc->s;
-
- if (gd_grab_on_hover(s)) {
- gd_grab_keyboard(vc, "grab-on-hover");
- }
- return TRUE;
-}
-
-static gboolean gd_leave_event(GtkWidget *widget, GdkEventCrossing *crossing,
- gpointer opaque)
-{
- VirtualConsole *vc = opaque;
- GtkDisplayState *s = vc->s;
-
- if (gd_grab_on_hover(s)) {
- gd_ungrab_keyboard(s);
- }
- return TRUE;
-}
-
-static gboolean gd_focus_out_event(GtkWidget *widget,
- GdkEventCrossing *crossing, gpointer opaque)
-{
- VirtualConsole *vc = opaque;
- GtkDisplayState *s = vc->s;
-
- gtk_release_modifiers(s);
- return TRUE;
-}
-
-static gboolean gd_configure(GtkWidget *widget,
- GdkEventConfigure *cfg, gpointer opaque)
-{
- VirtualConsole *vc = opaque;
-
- gd_set_ui_info(vc, cfg->width, cfg->height);
- return FALSE;
-}
-
-/** Virtual Console Callbacks **/
-
-static GSList *gd_vc_menu_init(GtkDisplayState *s, VirtualConsole *vc,
- int idx, GSList *group, GtkWidget *view_menu)
-{
- vc->menu_item = gtk_radio_menu_item_new_with_mnemonic(group, vc->label);
- gtk_accel_group_connect(s->accel_group, GDK_KEY_1 + idx,
- HOTKEY_MODIFIERS, 0,
- g_cclosure_new_swap(G_CALLBACK(gd_accel_switch_vc), vc, NULL));
-#if GTK_CHECK_VERSION(3, 8, 0)
- gtk_accel_label_set_accel(
- GTK_ACCEL_LABEL(gtk_bin_get_child(GTK_BIN(vc->menu_item))),
- GDK_KEY_1 + idx, HOTKEY_MODIFIERS);
-#endif
-
- g_signal_connect(vc->menu_item, "activate",
- G_CALLBACK(gd_menu_switch_vc), s);
- gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), vc->menu_item);
-
- group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(vc->menu_item));
- return group;
-}
-
-#if defined(CONFIG_VTE)
-static void gd_vc_adjustment_changed(GtkAdjustment *adjustment, void *opaque)
-{
- VirtualConsole *vc = opaque;
-
- if (gtk_adjustment_get_upper(adjustment) >
- gtk_adjustment_get_page_size(adjustment)) {
- gtk_widget_show(vc->vte.scrollbar);
- } else {
- gtk_widget_hide(vc->vte.scrollbar);
- }
-}
-
-static int gd_vc_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
-{
- VirtualConsole *vc = chr->opaque;
-
- vte_terminal_feed(VTE_TERMINAL(vc->vte.terminal), (const char *)buf, len);
- return len;
-}
-
-static void gd_vc_chr_set_echo(CharDriverState *chr, bool echo)
-{
- VirtualConsole *vc = chr->opaque;
-
- vc->vte.echo = echo;
-}
-
-static int nb_vcs;
-static CharDriverState *vcs[MAX_VCS];
-
-static CharDriverState *gd_vc_handler(ChardevVC *vc, Error **errp)
-{
- ChardevCommon *common = qapi_ChardevVC_base(vc);
- CharDriverState *chr;
-
- chr = qemu_chr_alloc(common, errp);
- if (!chr) {
- return NULL;
- }
-
- chr->chr_write = gd_vc_chr_write;
- chr->chr_set_echo = gd_vc_chr_set_echo;
-
- /* Temporary, until gd_vc_vte_init runs. */
- chr->opaque = g_new0(VirtualConsole, 1);
-
- /* defer OPENED events until our vc is fully initialized */
- chr->explicit_be_open = true;
-
- vcs[nb_vcs++] = chr;
-
- return chr;
-}
-
-static gboolean gd_vc_in(VteTerminal *terminal, gchar *text, guint size,
- gpointer user_data)
-{
- VirtualConsole *vc = user_data;
-
- if (vc->vte.echo) {
- VteTerminal *term = VTE_TERMINAL(vc->vte.terminal);
- int i;
- for (i = 0; i < size; i++) {
- uint8_t c = text[i];
- if (c >= 128 || isprint(c)) {
- /* 8-bit characters are considered printable. */
- vte_terminal_feed(term, &text[i], 1);
- } else if (c == '\r' || c == '\n') {
- vte_terminal_feed(term, "\r\n", 2);
- } else {
- char ctrl[2] = { '^', 0};
- ctrl[1] = text[i] ^ 64;
- vte_terminal_feed(term, ctrl, 2);
- }
- }
- }
-
- qemu_chr_be_write(vc->vte.chr, (uint8_t *)text, (unsigned int)size);
- return TRUE;
-}
-
-static GSList *gd_vc_vte_init(GtkDisplayState *s, VirtualConsole *vc,
- CharDriverState *chr, int idx,
- GSList *group, GtkWidget *view_menu)
-{
- char buffer[32];
- GtkWidget *box;
- GtkWidget *scrollbar;
- GtkAdjustment *vadjustment;
- VirtualConsole *tmp_vc = chr->opaque;
-
- vc->s = s;
- vc->vte.echo = tmp_vc->vte.echo;
-
- vc->vte.chr = chr;
- chr->opaque = vc;
- g_free(tmp_vc);
-
- snprintf(buffer, sizeof(buffer), "vc%d", idx);
- vc->label = g_strdup_printf("%s", vc->vte.chr->label
- ? vc->vte.chr->label : buffer);
- group = gd_vc_menu_init(s, vc, idx, group, view_menu);
-
- vc->vte.terminal = vte_terminal_new();
- g_signal_connect(vc->vte.terminal, "commit", G_CALLBACK(gd_vc_in), vc);
-
- /* The documentation says that the default is UTF-8, but actually it is
- * 7-bit ASCII at least in VTE 0.38.
- */
-#if VTE_CHECK_VERSION(0, 40, 0)
- vte_terminal_set_encoding(VTE_TERMINAL(vc->vte.terminal), "UTF-8", NULL);
-#else
- vte_terminal_set_encoding(VTE_TERMINAL(vc->vte.terminal), "UTF-8");
-#endif
-
- vte_terminal_set_scrollback_lines(VTE_TERMINAL(vc->vte.terminal), -1);
- vte_terminal_set_size(VTE_TERMINAL(vc->vte.terminal),
- VC_TERM_X_MIN, VC_TERM_Y_MIN);
-
-#if VTE_CHECK_VERSION(0, 28, 0) && GTK_CHECK_VERSION(3, 0, 0)
- vadjustment = gtk_scrollable_get_vadjustment
- (GTK_SCROLLABLE(vc->vte.terminal));
-#else
- vadjustment = vte_terminal_get_adjustment(VTE_TERMINAL(vc->vte.terminal));
-#endif
-
-#if GTK_CHECK_VERSION(3, 0, 0)
- box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
- scrollbar = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, vadjustment);
-#else
- box = gtk_hbox_new(false, 2);
- scrollbar = gtk_vscrollbar_new(vadjustment);
-#endif
-
- gtk_box_pack_start(GTK_BOX(box), vc->vte.terminal, TRUE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(box), scrollbar, FALSE, FALSE, 0);
-
- vc->vte.box = box;
- vc->vte.scrollbar = scrollbar;
-
- g_signal_connect(vadjustment, "changed",
- G_CALLBACK(gd_vc_adjustment_changed), vc);
-
- vc->type = GD_VC_VTE;
- vc->tab_item = box;
- vc->focus = vc->vte.terminal;
- gtk_notebook_append_page(GTK_NOTEBOOK(s->notebook), vc->tab_item,
- gtk_label_new(vc->label));
-
- qemu_chr_be_generic_open(vc->vte.chr);
- if (vc->vte.chr->init) {
- vc->vte.chr->init(vc->vte.chr);
- }
-
- return group;
-}
-
-static void gd_vcs_init(GtkDisplayState *s, GSList *group,
- GtkWidget *view_menu)
-{
- int i;
-
- for (i = 0; i < nb_vcs; i++) {
- VirtualConsole *vc = &s->vc[s->nb_vcs];
- group = gd_vc_vte_init(s, vc, vcs[i], s->nb_vcs, group, view_menu);
- s->nb_vcs++;
- }
-}
-#endif /* CONFIG_VTE */
-
-/** Window Creation **/
-
-static void gd_connect_vc_gfx_signals(VirtualConsole *vc)
-{
-#if GTK_CHECK_VERSION(3, 0, 0)
- g_signal_connect(vc->gfx.drawing_area, "draw",
- G_CALLBACK(gd_draw_event), vc);
-#if defined(CONFIG_GTK_GL)
- if (display_opengl) {
- /* wire up GtkGlArea events */
- g_signal_connect(vc->gfx.drawing_area, "render",
- G_CALLBACK(gd_render_event), vc);
- g_signal_connect(vc->gfx.drawing_area, "resize",
- G_CALLBACK(gd_resize_event), vc);
- }
-#endif
-#else
- g_signal_connect(vc->gfx.drawing_area, "expose-event",
- G_CALLBACK(gd_expose_event), vc);
-#endif
- if (qemu_console_is_graphic(vc->gfx.dcl.con)) {
- g_signal_connect(vc->gfx.drawing_area, "event",
- G_CALLBACK(gd_event), vc);
- g_signal_connect(vc->gfx.drawing_area, "button-press-event",
- G_CALLBACK(gd_button_event), vc);
- g_signal_connect(vc->gfx.drawing_area, "button-release-event",
- G_CALLBACK(gd_button_event), vc);
- g_signal_connect(vc->gfx.drawing_area, "scroll-event",
- G_CALLBACK(gd_scroll_event), vc);
- g_signal_connect(vc->gfx.drawing_area, "key-press-event",
- G_CALLBACK(gd_key_event), vc);
- g_signal_connect(vc->gfx.drawing_area, "key-release-event",
- G_CALLBACK(gd_key_event), vc);
-
- g_signal_connect(vc->gfx.drawing_area, "enter-notify-event",
- G_CALLBACK(gd_enter_event), vc);
- g_signal_connect(vc->gfx.drawing_area, "leave-notify-event",
- G_CALLBACK(gd_leave_event), vc);
- g_signal_connect(vc->gfx.drawing_area, "focus-out-event",
- G_CALLBACK(gd_focus_out_event), vc);
- g_signal_connect(vc->gfx.drawing_area, "configure-event",
- G_CALLBACK(gd_configure), vc);
- } else {
- g_signal_connect(vc->gfx.drawing_area, "key-press-event",
- G_CALLBACK(gd_text_key_down), vc);
- }
-}
-
-static void gd_connect_signals(GtkDisplayState *s)
-{
- g_signal_connect(s->show_tabs_item, "activate",
- G_CALLBACK(gd_menu_show_tabs), s);
- g_signal_connect(s->untabify_item, "activate",
- G_CALLBACK(gd_menu_untabify), s);
-
- g_signal_connect(s->window, "delete-event",
- G_CALLBACK(gd_window_close), s);
-
- g_signal_connect(s->pause_item, "activate",
- G_CALLBACK(gd_menu_pause), s);
- g_signal_connect(s->reset_item, "activate",
- G_CALLBACK(gd_menu_reset), s);
- g_signal_connect(s->powerdown_item, "activate",
- G_CALLBACK(gd_menu_powerdown), s);
- g_signal_connect(s->quit_item, "activate",
- G_CALLBACK(gd_menu_quit), s);
- g_signal_connect(s->full_screen_item, "activate",
- G_CALLBACK(gd_menu_full_screen), s);
- g_signal_connect(s->zoom_in_item, "activate",
- G_CALLBACK(gd_menu_zoom_in), s);
- g_signal_connect(s->zoom_out_item, "activate",
- G_CALLBACK(gd_menu_zoom_out), s);
- g_signal_connect(s->zoom_fixed_item, "activate",
- G_CALLBACK(gd_menu_zoom_fixed), s);
- g_signal_connect(s->zoom_fit_item, "activate",
- G_CALLBACK(gd_menu_zoom_fit), s);
- g_signal_connect(s->grab_item, "activate",
- G_CALLBACK(gd_menu_grab_input), s);
- g_signal_connect(s->notebook, "switch-page",
- G_CALLBACK(gd_change_page), s);
-}
-
-static GtkWidget *gd_create_menu_machine(GtkDisplayState *s)
-{
- GtkWidget *machine_menu;
- GtkWidget *separator;
-
- machine_menu = gtk_menu_new();
- gtk_menu_set_accel_group(GTK_MENU(machine_menu), s->accel_group);
-
- s->pause_item = gtk_check_menu_item_new_with_mnemonic(_("_Pause"));
- gtk_menu_shell_append(GTK_MENU_SHELL(machine_menu), s->pause_item);
-
- separator = gtk_separator_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(machine_menu), separator);
-
- s->reset_item = gtk_menu_item_new_with_mnemonic(_("_Reset"));
- gtk_menu_shell_append(GTK_MENU_SHELL(machine_menu), s->reset_item);
-
- s->powerdown_item = gtk_menu_item_new_with_mnemonic(_("Power _Down"));
- gtk_menu_shell_append(GTK_MENU_SHELL(machine_menu), s->powerdown_item);
-
- separator = gtk_separator_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(machine_menu), separator);
-
- s->quit_item = gtk_menu_item_new_with_mnemonic(_("_Quit"));
- gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->quit_item),
- "<QEMU>/Machine/Quit");
- gtk_accel_map_add_entry("<QEMU>/Machine/Quit",
- GDK_KEY_q, HOTKEY_MODIFIERS);
- gtk_menu_shell_append(GTK_MENU_SHELL(machine_menu), s->quit_item);
-
- return machine_menu;
-}
-
-static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc,
- QemuConsole *con, int idx,
- GSList *group, GtkWidget *view_menu)
-{
- vc->label = qemu_console_get_label(con);
- vc->s = s;
- vc->gfx.scale_x = 1.0;
- vc->gfx.scale_y = 1.0;
-
-#if defined(CONFIG_OPENGL)
- if (display_opengl) {
-#if defined(CONFIG_GTK_GL)
- vc->gfx.drawing_area = gtk_gl_area_new();
- vc->gfx.dcl.ops = &dcl_gl_area_ops;
-#else
- vc->gfx.drawing_area = gtk_drawing_area_new();
- /*
- * gtk_widget_set_double_buffered() was deprecated in 3.14.
- * It is required for opengl rendering on X11 though. A
- * proper replacement (native opengl support) is only
- * available in 3.16+. Silence the warning if possible.
- */
-#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#endif
- gtk_widget_set_double_buffered(vc->gfx.drawing_area, FALSE);
-#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE
-#pragma GCC diagnostic pop
-#endif
- vc->gfx.dcl.ops = &dcl_egl_ops;
-#endif /* CONFIG_GTK_GL */
- } else
-#endif
- {
- vc->gfx.drawing_area = gtk_drawing_area_new();
- vc->gfx.dcl.ops = &dcl_ops;
- }
-
-
- gtk_widget_add_events(vc->gfx.drawing_area,
- GDK_POINTER_MOTION_MASK |
- GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK |
- GDK_BUTTON_MOTION_MASK |
- GDK_ENTER_NOTIFY_MASK |
- GDK_LEAVE_NOTIFY_MASK |
- GDK_SCROLL_MASK |
- GDK_KEY_PRESS_MASK);
- gtk_widget_set_can_focus(vc->gfx.drawing_area, TRUE);
-
- vc->type = GD_VC_GFX;
- vc->tab_item = vc->gfx.drawing_area;
- vc->focus = vc->gfx.drawing_area;
- gtk_notebook_append_page(GTK_NOTEBOOK(s->notebook),
- vc->tab_item, gtk_label_new(vc->label));
-
- vc->gfx.dcl.con = con;
- register_displaychangelistener(&vc->gfx.dcl);
-
- gd_connect_vc_gfx_signals(vc);
- group = gd_vc_menu_init(s, vc, idx, group, view_menu);
-
- if (dpy_ui_info_supported(vc->gfx.dcl.con)) {
- gtk_menu_item_activate(GTK_MENU_ITEM(s->zoom_fit_item));
- s->free_scale = true;
- }
-
- return group;
-}
-
-static GtkWidget *gd_create_menu_view(GtkDisplayState *s)
-{
- GSList *group = NULL;
- GtkWidget *view_menu;
- GtkWidget *separator;
- QemuConsole *con;
- int vc;
-
- view_menu = gtk_menu_new();
- gtk_menu_set_accel_group(GTK_MENU(view_menu), s->accel_group);
-
- s->full_screen_item = gtk_menu_item_new_with_mnemonic(_("_Fullscreen"));
-
- gtk_accel_group_connect(s->accel_group, GDK_KEY_f, HOTKEY_MODIFIERS, 0,
- g_cclosure_new_swap(G_CALLBACK(gd_accel_full_screen), s, NULL));
-#if GTK_CHECK_VERSION(3, 8, 0)
- gtk_accel_label_set_accel(
- GTK_ACCEL_LABEL(gtk_bin_get_child(GTK_BIN(s->full_screen_item))),
- GDK_KEY_f, HOTKEY_MODIFIERS);
-#endif
- gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->full_screen_item);
-
- separator = gtk_separator_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), separator);
-
- s->zoom_in_item = gtk_menu_item_new_with_mnemonic(_("Zoom _In"));
- gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->zoom_in_item),
- "<QEMU>/View/Zoom In");
- gtk_accel_map_add_entry("<QEMU>/View/Zoom In", GDK_KEY_plus,
- HOTKEY_MODIFIERS);
- gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->zoom_in_item);
-
- s->zoom_out_item = gtk_menu_item_new_with_mnemonic(_("Zoom _Out"));
- gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->zoom_out_item),
- "<QEMU>/View/Zoom Out");
- gtk_accel_map_add_entry("<QEMU>/View/Zoom Out", GDK_KEY_minus,
- HOTKEY_MODIFIERS);
- gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->zoom_out_item);
-
- s->zoom_fixed_item = gtk_menu_item_new_with_mnemonic(_("Best _Fit"));
- gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->zoom_fixed_item),
- "<QEMU>/View/Zoom Fixed");
- gtk_accel_map_add_entry("<QEMU>/View/Zoom Fixed", GDK_KEY_0,
- HOTKEY_MODIFIERS);
- gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->zoom_fixed_item);
-
- s->zoom_fit_item = gtk_check_menu_item_new_with_mnemonic(_("Zoom To _Fit"));
- gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->zoom_fit_item);
-
- separator = gtk_separator_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), separator);
-
- s->grab_on_hover_item = gtk_check_menu_item_new_with_mnemonic(_("Grab On _Hover"));
- gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->grab_on_hover_item);
-
- s->grab_item = gtk_check_menu_item_new_with_mnemonic(_("_Grab Input"));
- gtk_menu_item_set_accel_path(GTK_MENU_ITEM(s->grab_item),
- "<QEMU>/View/Grab Input");
- gtk_accel_map_add_entry("<QEMU>/View/Grab Input", GDK_KEY_g,
- HOTKEY_MODIFIERS);
- gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->grab_item);
-
- separator = gtk_separator_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), separator);
-
- /* gfx */
- for (vc = 0;; vc++) {
- con = qemu_console_lookup_by_index(vc);
- if (!con) {
- break;
- }
- group = gd_vc_gfx_init(s, &s->vc[vc], con,
- vc, group, view_menu);
- s->nb_vcs++;
- }
-
-#if defined(CONFIG_VTE)
- /* vte */
- gd_vcs_init(s, group, view_menu);
-#endif
-
- separator = gtk_separator_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), separator);
-
- s->show_tabs_item = gtk_check_menu_item_new_with_mnemonic(_("Show _Tabs"));
- gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->show_tabs_item);
-
- s->untabify_item = gtk_menu_item_new_with_mnemonic(_("Detach Tab"));
- gtk_menu_shell_append(GTK_MENU_SHELL(view_menu), s->untabify_item);
-
- return view_menu;
-}
-
-static void gd_create_menus(GtkDisplayState *s)
-{
- s->accel_group = gtk_accel_group_new();
- s->machine_menu = gd_create_menu_machine(s);
- s->view_menu = gd_create_menu_view(s);
-
- s->machine_menu_item = gtk_menu_item_new_with_mnemonic(_("_Machine"));
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(s->machine_menu_item),
- s->machine_menu);
- gtk_menu_shell_append(GTK_MENU_SHELL(s->menu_bar), s->machine_menu_item);
-
- s->view_menu_item = gtk_menu_item_new_with_mnemonic(_("_View"));
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(s->view_menu_item), s->view_menu);
- gtk_menu_shell_append(GTK_MENU_SHELL(s->menu_bar), s->view_menu_item);
-
- g_object_set_data(G_OBJECT(s->window), "accel_group", s->accel_group);
- gtk_window_add_accel_group(GTK_WINDOW(s->window), s->accel_group);
-}
-
-static void gd_set_keycode_type(GtkDisplayState *s)
-{
-#ifdef GDK_WINDOWING_X11
- GdkDisplay *display = gtk_widget_get_display(s->window);
- if (GDK_IS_X11_DISPLAY(display)) {
- Display *x11_display = gdk_x11_display_get_xdisplay(display);
- XkbDescPtr desc = XkbGetKeyboard(x11_display, XkbGBN_AllComponentsMask,
- XkbUseCoreKbd);
- char *keycodes = NULL;
-
- if (desc && desc->names) {
- keycodes = XGetAtomName(x11_display, desc->names->keycodes);
- }
- if (keycodes == NULL) {
- fprintf(stderr, "could not lookup keycode name\n");
- } else if (strstart(keycodes, "evdev", NULL)) {
- s->has_evdev = true;
- } else if (!strstart(keycodes, "xfree86", NULL)) {
- fprintf(stderr, "unknown keycodes `%s', please report to "
- "qemu-devel@nongnu.org\n", keycodes);
- }
-
- if (desc) {
- XkbFreeKeyboard(desc, XkbGBN_AllComponentsMask, True);
- }
- if (keycodes) {
- XFree(keycodes);
- }
- }
-#endif
-}
-
-static gboolean gtkinit;
-
-void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover)
-{
- GtkDisplayState *s = g_malloc0(sizeof(*s));
- char *filename;
- GdkDisplay *window_display;
-
- if (!gtkinit) {
- fprintf(stderr, "gtk initialization failed\n");
- exit(1);
- }
-
- s->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-#if GTK_CHECK_VERSION(3, 2, 0)
- s->vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
-#else
- s->vbox = gtk_vbox_new(FALSE, 0);
-#endif
- s->notebook = gtk_notebook_new();
- s->menu_bar = gtk_menu_bar_new();
-
- s->free_scale = FALSE;
-
- /* LC_MESSAGES only. See early_gtk_display_init() for details */
- setlocale(LC_MESSAGES, "");
- bindtextdomain("qemu", CONFIG_QEMU_LOCALEDIR);
- textdomain("qemu");
-
- window_display = gtk_widget_get_display(s->window);
- s->null_cursor = gdk_cursor_new_for_display(window_display,
- GDK_BLANK_CURSOR);
-
- s->mouse_mode_notifier.notify = gd_mouse_mode_change;
- qemu_add_mouse_mode_change_notifier(&s->mouse_mode_notifier);
- qemu_add_vm_change_state_handler(gd_change_runstate, s);
-
- filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "qemu_logo_no_text.svg");
- if (filename) {
- GError *error = NULL;
- GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(filename, &error);
- if (pixbuf) {
- gtk_window_set_icon(GTK_WINDOW(s->window), pixbuf);
- } else {
- g_error_free(error);
- }
- g_free(filename);
- }
-
- gd_create_menus(s);
-
- gd_connect_signals(s);
-
- gtk_notebook_set_show_tabs(GTK_NOTEBOOK(s->notebook), FALSE);
- gtk_notebook_set_show_border(GTK_NOTEBOOK(s->notebook), FALSE);
-
- gd_update_caption(s);
-
- gtk_box_pack_start(GTK_BOX(s->vbox), s->menu_bar, FALSE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(s->vbox), s->notebook, TRUE, TRUE, 0);
-
- gtk_container_add(GTK_CONTAINER(s->window), s->vbox);
-
- gtk_widget_show_all(s->window);
-
-#ifdef VTE_RESIZE_HACK
- {
- VirtualConsole *cur = gd_vc_find_current(s);
- if (cur) {
- int i;
-
- for (i = 0; i < s->nb_vcs; i++) {
- VirtualConsole *vc = &s->vc[i];
- if (vc && vc->type == GD_VC_VTE && vc != cur) {
- gtk_widget_hide(vc->vte.terminal);
- }
- }
- gd_update_windowsize(cur);
- }
- }
-#endif
-
- if (full_screen) {
- gtk_menu_item_activate(GTK_MENU_ITEM(s->full_screen_item));
- }
- if (grab_on_hover) {
- gtk_menu_item_activate(GTK_MENU_ITEM(s->grab_on_hover_item));
- }
-
- gd_set_keycode_type(s);
-}
-
-void early_gtk_display_init(int opengl)
-{
- /* The QEMU code relies on the assumption that it's always run in
- * the C locale. Therefore it is not prepared to deal with
- * operations that produce different results depending on the
- * locale, such as printf's formatting of decimal numbers, and
- * possibly others.
- *
- * Since GTK+ calls setlocale() by default -importing the locale
- * settings from the environment- we must prevent it from doing so
- * using gtk_disable_setlocale().
- *
- * QEMU's GTK+ UI, however, _does_ have translations for some of
- * the menu items. As a trade-off between a functionally correct
- * QEMU and a fully internationalized UI we support importing
- * LC_MESSAGES from the environment (see the setlocale() call
- * earlier in this file). This allows us to display translated
- * messages leaving everything else untouched.
- */
- gtk_disable_setlocale();
- gtkinit = gtk_init_check(NULL, NULL);
- if (!gtkinit) {
- /* don't exit yet, that'll break -help */
- return;
- }
-
- switch (opengl) {
- case -1: /* default */
- case 0: /* off */
- break;
- case 1: /* on */
-#if defined(CONFIG_OPENGL)
-#if defined(CONFIG_GTK_GL)
- gtk_gl_area_init();
-#else
- gtk_egl_init();
-#endif
-#endif
- break;
- default:
- g_assert_not_reached();
- break;
- }
-
-#if defined(CONFIG_VTE)
- register_vc_handler(gd_vc_handler);
-#endif
-}
diff --git a/qemu/ui/input-keymap.c b/qemu/ui/input-keymap.c
deleted file mode 100644
index f1e700d72..000000000
--- a/qemu/ui/input-keymap.c
+++ /dev/null
@@ -1,203 +0,0 @@
-#include "qemu/osdep.h"
-#include "sysemu/sysemu.h"
-#include "ui/keymaps.h"
-#include "ui/input.h"
-
-static const int qcode_to_number[] = {
- [Q_KEY_CODE_SHIFT] = 0x2a,
- [Q_KEY_CODE_SHIFT_R] = 0x36,
-
- [Q_KEY_CODE_ALT] = 0x38,
- [Q_KEY_CODE_ALT_R] = 0xb8,
- [Q_KEY_CODE_ALTGR] = 0x64,
- [Q_KEY_CODE_ALTGR_R] = 0xe4,
- [Q_KEY_CODE_CTRL] = 0x1d,
- [Q_KEY_CODE_CTRL_R] = 0x9d,
-
- [Q_KEY_CODE_META_L] = 0xdb,
- [Q_KEY_CODE_META_R] = 0xdc,
- [Q_KEY_CODE_MENU] = 0xdd,
-
- [Q_KEY_CODE_ESC] = 0x01,
-
- [Q_KEY_CODE_1] = 0x02,
- [Q_KEY_CODE_2] = 0x03,
- [Q_KEY_CODE_3] = 0x04,
- [Q_KEY_CODE_4] = 0x05,
- [Q_KEY_CODE_5] = 0x06,
- [Q_KEY_CODE_6] = 0x07,
- [Q_KEY_CODE_7] = 0x08,
- [Q_KEY_CODE_8] = 0x09,
- [Q_KEY_CODE_9] = 0x0a,
- [Q_KEY_CODE_0] = 0x0b,
- [Q_KEY_CODE_MINUS] = 0x0c,
- [Q_KEY_CODE_EQUAL] = 0x0d,
- [Q_KEY_CODE_BACKSPACE] = 0x0e,
-
- [Q_KEY_CODE_TAB] = 0x0f,
- [Q_KEY_CODE_Q] = 0x10,
- [Q_KEY_CODE_W] = 0x11,
- [Q_KEY_CODE_E] = 0x12,
- [Q_KEY_CODE_R] = 0x13,
- [Q_KEY_CODE_T] = 0x14,
- [Q_KEY_CODE_Y] = 0x15,
- [Q_KEY_CODE_U] = 0x16,
- [Q_KEY_CODE_I] = 0x17,
- [Q_KEY_CODE_O] = 0x18,
- [Q_KEY_CODE_P] = 0x19,
- [Q_KEY_CODE_BRACKET_LEFT] = 0x1a,
- [Q_KEY_CODE_BRACKET_RIGHT] = 0x1b,
- [Q_KEY_CODE_RET] = 0x1c,
-
- [Q_KEY_CODE_A] = 0x1e,
- [Q_KEY_CODE_S] = 0x1f,
- [Q_KEY_CODE_D] = 0x20,
- [Q_KEY_CODE_F] = 0x21,
- [Q_KEY_CODE_G] = 0x22,
- [Q_KEY_CODE_H] = 0x23,
- [Q_KEY_CODE_J] = 0x24,
- [Q_KEY_CODE_K] = 0x25,
- [Q_KEY_CODE_L] = 0x26,
- [Q_KEY_CODE_SEMICOLON] = 0x27,
- [Q_KEY_CODE_APOSTROPHE] = 0x28,
- [Q_KEY_CODE_GRAVE_ACCENT] = 0x29,
-
- [Q_KEY_CODE_BACKSLASH] = 0x2b,
- [Q_KEY_CODE_Z] = 0x2c,
- [Q_KEY_CODE_X] = 0x2d,
- [Q_KEY_CODE_C] = 0x2e,
- [Q_KEY_CODE_V] = 0x2f,
- [Q_KEY_CODE_B] = 0x30,
- [Q_KEY_CODE_N] = 0x31,
- [Q_KEY_CODE_M] = 0x32,
- [Q_KEY_CODE_COMMA] = 0x33,
- [Q_KEY_CODE_DOT] = 0x34,
- [Q_KEY_CODE_SLASH] = 0x35,
-
- [Q_KEY_CODE_ASTERISK] = 0x37,
-
- [Q_KEY_CODE_SPC] = 0x39,
- [Q_KEY_CODE_CAPS_LOCK] = 0x3a,
- [Q_KEY_CODE_F1] = 0x3b,
- [Q_KEY_CODE_F2] = 0x3c,
- [Q_KEY_CODE_F3] = 0x3d,
- [Q_KEY_CODE_F4] = 0x3e,
- [Q_KEY_CODE_F5] = 0x3f,
- [Q_KEY_CODE_F6] = 0x40,
- [Q_KEY_CODE_F7] = 0x41,
- [Q_KEY_CODE_F8] = 0x42,
- [Q_KEY_CODE_F9] = 0x43,
- [Q_KEY_CODE_F10] = 0x44,
- [Q_KEY_CODE_NUM_LOCK] = 0x45,
- [Q_KEY_CODE_SCROLL_LOCK] = 0x46,
-
- [Q_KEY_CODE_KP_DIVIDE] = 0xb5,
- [Q_KEY_CODE_KP_MULTIPLY] = 0x37,
- [Q_KEY_CODE_KP_SUBTRACT] = 0x4a,
- [Q_KEY_CODE_KP_ADD] = 0x4e,
- [Q_KEY_CODE_KP_ENTER] = 0x9c,
- [Q_KEY_CODE_KP_DECIMAL] = 0x53,
- [Q_KEY_CODE_SYSRQ] = 0x54,
-
- [Q_KEY_CODE_KP_0] = 0x52,
- [Q_KEY_CODE_KP_1] = 0x4f,
- [Q_KEY_CODE_KP_2] = 0x50,
- [Q_KEY_CODE_KP_3] = 0x51,
- [Q_KEY_CODE_KP_4] = 0x4b,
- [Q_KEY_CODE_KP_5] = 0x4c,
- [Q_KEY_CODE_KP_6] = 0x4d,
- [Q_KEY_CODE_KP_7] = 0x47,
- [Q_KEY_CODE_KP_8] = 0x48,
- [Q_KEY_CODE_KP_9] = 0x49,
-
- [Q_KEY_CODE_LESS] = 0x56,
-
- [Q_KEY_CODE_F11] = 0x57,
- [Q_KEY_CODE_F12] = 0x58,
-
- [Q_KEY_CODE_PRINT] = 0xb7,
-
- [Q_KEY_CODE_HOME] = 0xc7,
- [Q_KEY_CODE_PGUP] = 0xc9,
- [Q_KEY_CODE_PGDN] = 0xd1,
- [Q_KEY_CODE_END] = 0xcf,
-
- [Q_KEY_CODE_LEFT] = 0xcb,
- [Q_KEY_CODE_UP] = 0xc8,
- [Q_KEY_CODE_DOWN] = 0xd0,
- [Q_KEY_CODE_RIGHT] = 0xcd,
-
- [Q_KEY_CODE_INSERT] = 0xd2,
- [Q_KEY_CODE_DELETE] = 0xd3,
-
- [Q_KEY_CODE_RO] = 0x73,
- [Q_KEY_CODE_KP_COMMA] = 0x7e,
-
- [Q_KEY_CODE__MAX] = 0,
-};
-
-static int number_to_qcode[0x100];
-
-int qemu_input_key_value_to_number(const KeyValue *value)
-{
- if (value->type == KEY_VALUE_KIND_QCODE) {
- return qcode_to_number[value->u.qcode.data];
- } else {
- assert(value->type == KEY_VALUE_KIND_NUMBER);
- return value->u.number.data;
- }
-}
-
-int qemu_input_key_number_to_qcode(uint8_t nr)
-{
- static int first = true;
-
- if (first) {
- int qcode, number;
- first = false;
- for (qcode = 0; qcode < Q_KEY_CODE__MAX; qcode++) {
- number = qcode_to_number[qcode];
- assert(number < ARRAY_SIZE(number_to_qcode));
- number_to_qcode[number] = qcode;
- }
- }
-
- return number_to_qcode[nr];
-}
-
-int qemu_input_key_value_to_qcode(const KeyValue *value)
-{
- if (value->type == KEY_VALUE_KIND_QCODE) {
- return value->u.qcode.data;
- } else {
- assert(value->type == KEY_VALUE_KIND_NUMBER);
- return qemu_input_key_number_to_qcode(value->u.number.data);
- }
-}
-
-int qemu_input_key_value_to_scancode(const KeyValue *value, bool down,
- int *codes)
-{
- int keycode = qemu_input_key_value_to_number(value);
- int count = 0;
-
- if (value->type == KEY_VALUE_KIND_QCODE &&
- value->u.qcode.data == Q_KEY_CODE_PAUSE) {
- /* specific case */
- int v = down ? 0 : 0x80;
- codes[count++] = 0xe1;
- codes[count++] = 0x1d | v;
- codes[count++] = 0x45 | v;
- return count;
- }
- if (keycode & SCANCODE_GREY) {
- codes[count++] = SCANCODE_EMUL0;
- keycode &= ~SCANCODE_GREY;
- }
- if (!down) {
- keycode |= SCANCODE_UP;
- }
- codes[count++] = keycode;
-
- return count;
-}
diff --git a/qemu/ui/input-legacy.c b/qemu/ui/input-legacy.c
deleted file mode 100644
index 715974740..000000000
--- a/qemu/ui/input-legacy.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * QEMU System Emulator
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "sysemu/sysemu.h"
-#include "ui/console.h"
-#include "qmp-commands.h"
-#include "qapi-types.h"
-#include "ui/keymaps.h"
-#include "ui/input.h"
-
-struct QEMUPutMouseEntry {
- QEMUPutMouseEvent *qemu_put_mouse_event;
- void *qemu_put_mouse_event_opaque;
- int qemu_put_mouse_event_absolute;
-
- /* new input core */
- QemuInputHandler h;
- QemuInputHandlerState *s;
- int axis[INPUT_AXIS__MAX];
- int buttons;
-};
-
-struct QEMUPutKbdEntry {
- QEMUPutKBDEvent *put_kbd;
- void *opaque;
- QemuInputHandlerState *s;
-};
-
-struct QEMUPutLEDEntry {
- QEMUPutLEDEvent *put_led;
- void *opaque;
- QTAILQ_ENTRY(QEMUPutLEDEntry) next;
-};
-
-static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers =
- QTAILQ_HEAD_INITIALIZER(led_handlers);
-
-int index_from_key(const char *key, size_t key_length)
-{
- int i;
-
- for (i = 0; QKeyCode_lookup[i] != NULL; i++) {
- if (!strncmp(key, QKeyCode_lookup[i], key_length) &&
- !QKeyCode_lookup[i][key_length]) {
- break;
- }
- }
-
- /* Return Q_KEY_CODE__MAX if the key is invalid */
- return i;
-}
-
-static KeyValue *copy_key_value(KeyValue *src)
-{
- KeyValue *dst = g_new(KeyValue, 1);
- memcpy(dst, src, sizeof(*src));
- return dst;
-}
-
-void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time,
- Error **errp)
-{
- KeyValueList *p;
- KeyValue **up = NULL;
- int count = 0;
-
- if (!has_hold_time) {
- hold_time = 0; /* use default */
- }
-
- for (p = keys; p != NULL; p = p->next) {
- qemu_input_event_send_key(NULL, copy_key_value(p->value), true);
- qemu_input_event_send_key_delay(hold_time);
- up = g_realloc(up, sizeof(*up) * (count+1));
- up[count] = copy_key_value(p->value);
- count++;
- }
- while (count) {
- count--;
- qemu_input_event_send_key(NULL, up[count], false);
- qemu_input_event_send_key_delay(hold_time);
- }
- g_free(up);
-}
-
-static void legacy_kbd_event(DeviceState *dev, QemuConsole *src,
- InputEvent *evt)
-{
- QEMUPutKbdEntry *entry = (QEMUPutKbdEntry *)dev;
- int scancodes[3], i, count;
- InputKeyEvent *key = evt->u.key.data;
-
- if (!entry || !entry->put_kbd) {
- return;
- }
- count = qemu_input_key_value_to_scancode(key->key,
- key->down,
- scancodes);
- for (i = 0; i < count; i++) {
- entry->put_kbd(entry->opaque, scancodes[i]);
- }
-}
-
-static QemuInputHandler legacy_kbd_handler = {
- .name = "legacy-kbd",
- .mask = INPUT_EVENT_MASK_KEY,
- .event = legacy_kbd_event,
-};
-
-QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
-{
- QEMUPutKbdEntry *entry;
-
- entry = g_new0(QEMUPutKbdEntry, 1);
- entry->put_kbd = func;
- entry->opaque = opaque;
- entry->s = qemu_input_handler_register((DeviceState *)entry,
- &legacy_kbd_handler);
- qemu_input_handler_activate(entry->s);
- return entry;
-}
-
-static void legacy_mouse_event(DeviceState *dev, QemuConsole *src,
- InputEvent *evt)
-{
- static const int bmap[INPUT_BUTTON__MAX] = {
- [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON,
- [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
- [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON,
- };
- QEMUPutMouseEntry *s = (QEMUPutMouseEntry *)dev;
- InputBtnEvent *btn;
- InputMoveEvent *move;
-
- switch (evt->type) {
- case INPUT_EVENT_KIND_BTN:
- btn = evt->u.btn.data;
- if (btn->down) {
- s->buttons |= bmap[btn->button];
- } else {
- s->buttons &= ~bmap[btn->button];
- }
- if (btn->down && btn->button == INPUT_BUTTON_WHEEL_UP) {
- s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
- s->axis[INPUT_AXIS_X],
- s->axis[INPUT_AXIS_Y],
- -1,
- s->buttons);
- }
- if (btn->down && btn->button == INPUT_BUTTON_WHEEL_DOWN) {
- s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
- s->axis[INPUT_AXIS_X],
- s->axis[INPUT_AXIS_Y],
- 1,
- s->buttons);
- }
- break;
- case INPUT_EVENT_KIND_ABS:
- move = evt->u.abs.data;
- s->axis[move->axis] = move->value;
- break;
- case INPUT_EVENT_KIND_REL:
- move = evt->u.rel.data;
- s->axis[move->axis] += move->value;
- break;
- default:
- break;
- }
-}
-
-static void legacy_mouse_sync(DeviceState *dev)
-{
- QEMUPutMouseEntry *s = (QEMUPutMouseEntry *)dev;
-
- s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
- s->axis[INPUT_AXIS_X],
- s->axis[INPUT_AXIS_Y],
- 0,
- s->buttons);
-
- if (!s->qemu_put_mouse_event_absolute) {
- s->axis[INPUT_AXIS_X] = 0;
- s->axis[INPUT_AXIS_Y] = 0;
- }
-}
-
-QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
- void *opaque, int absolute,
- const char *name)
-{
- QEMUPutMouseEntry *s;
-
- s = g_new0(QEMUPutMouseEntry, 1);
-
- s->qemu_put_mouse_event = func;
- s->qemu_put_mouse_event_opaque = opaque;
- s->qemu_put_mouse_event_absolute = absolute;
-
- s->h.name = name;
- s->h.mask = INPUT_EVENT_MASK_BTN |
- (absolute ? INPUT_EVENT_MASK_ABS : INPUT_EVENT_MASK_REL);
- s->h.event = legacy_mouse_event;
- s->h.sync = legacy_mouse_sync;
- s->s = qemu_input_handler_register((DeviceState *)s,
- &s->h);
-
- return s;
-}
-
-void qemu_activate_mouse_event_handler(QEMUPutMouseEntry *entry)
-{
- qemu_input_handler_activate(entry->s);
-}
-
-void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
-{
- qemu_input_handler_unregister(entry->s);
-
- g_free(entry);
-}
-
-QEMUPutLEDEntry *qemu_add_led_event_handler(QEMUPutLEDEvent *func,
- void *opaque)
-{
- QEMUPutLEDEntry *s;
-
- s = g_new0(QEMUPutLEDEntry, 1);
-
- s->put_led = func;
- s->opaque = opaque;
- QTAILQ_INSERT_TAIL(&led_handlers, s, next);
- return s;
-}
-
-void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry)
-{
- if (entry == NULL)
- return;
- QTAILQ_REMOVE(&led_handlers, entry, next);
- g_free(entry);
-}
-
-void kbd_put_ledstate(int ledstate)
-{
- QEMUPutLEDEntry *cursor;
-
- QTAILQ_FOREACH(cursor, &led_handlers, next) {
- cursor->put_led(cursor->opaque, ledstate);
- }
-}
diff --git a/qemu/ui/input-linux.c b/qemu/ui/input-linux.c
deleted file mode 100644
index 1d33b5c12..000000000
--- a/qemu/ui/input-linux.c
+++ /dev/null
@@ -1,507 +0,0 @@
-/*
- * This work is licensed under the terms of the GNU GPL, version 2 or
- * (at your option) any later version. See the COPYING file in the
- * top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu-common.h"
-#include "qemu/config-file.h"
-#include "qemu/sockets.h"
-#include "sysemu/sysemu.h"
-#include "ui/input.h"
-#include "qom/object_interfaces.h"
-
-#include <sys/ioctl.h>
-#include "standard-headers/linux/input.h"
-
-static int linux_to_qcode[KEY_CNT] = {
- [KEY_ESC] = Q_KEY_CODE_ESC,
- [KEY_1] = Q_KEY_CODE_1,
- [KEY_2] = Q_KEY_CODE_2,
- [KEY_3] = Q_KEY_CODE_3,
- [KEY_4] = Q_KEY_CODE_4,
- [KEY_5] = Q_KEY_CODE_5,
- [KEY_6] = Q_KEY_CODE_6,
- [KEY_7] = Q_KEY_CODE_7,
- [KEY_8] = Q_KEY_CODE_8,
- [KEY_9] = Q_KEY_CODE_9,
- [KEY_0] = Q_KEY_CODE_0,
- [KEY_MINUS] = Q_KEY_CODE_MINUS,
- [KEY_EQUAL] = Q_KEY_CODE_EQUAL,
- [KEY_BACKSPACE] = Q_KEY_CODE_BACKSPACE,
- [KEY_TAB] = Q_KEY_CODE_TAB,
- [KEY_Q] = Q_KEY_CODE_Q,
- [KEY_W] = Q_KEY_CODE_W,
- [KEY_E] = Q_KEY_CODE_E,
- [KEY_R] = Q_KEY_CODE_R,
- [KEY_T] = Q_KEY_CODE_T,
- [KEY_Y] = Q_KEY_CODE_Y,
- [KEY_U] = Q_KEY_CODE_U,
- [KEY_I] = Q_KEY_CODE_I,
- [KEY_O] = Q_KEY_CODE_O,
- [KEY_P] = Q_KEY_CODE_P,
- [KEY_LEFTBRACE] = Q_KEY_CODE_BRACKET_LEFT,
- [KEY_RIGHTBRACE] = Q_KEY_CODE_BRACKET_RIGHT,
- [KEY_ENTER] = Q_KEY_CODE_RET,
- [KEY_LEFTCTRL] = Q_KEY_CODE_CTRL,
- [KEY_A] = Q_KEY_CODE_A,
- [KEY_S] = Q_KEY_CODE_S,
- [KEY_D] = Q_KEY_CODE_D,
- [KEY_F] = Q_KEY_CODE_F,
- [KEY_G] = Q_KEY_CODE_G,
- [KEY_H] = Q_KEY_CODE_H,
- [KEY_J] = Q_KEY_CODE_J,
- [KEY_K] = Q_KEY_CODE_K,
- [KEY_L] = Q_KEY_CODE_L,
- [KEY_SEMICOLON] = Q_KEY_CODE_SEMICOLON,
- [KEY_APOSTROPHE] = Q_KEY_CODE_APOSTROPHE,
- [KEY_GRAVE] = Q_KEY_CODE_GRAVE_ACCENT,
- [KEY_LEFTSHIFT] = Q_KEY_CODE_SHIFT,
- [KEY_BACKSLASH] = Q_KEY_CODE_BACKSLASH,
- [KEY_102ND] = Q_KEY_CODE_LESS,
- [KEY_Z] = Q_KEY_CODE_Z,
- [KEY_X] = Q_KEY_CODE_X,
- [KEY_C] = Q_KEY_CODE_C,
- [KEY_V] = Q_KEY_CODE_V,
- [KEY_B] = Q_KEY_CODE_B,
- [KEY_N] = Q_KEY_CODE_N,
- [KEY_M] = Q_KEY_CODE_M,
- [KEY_COMMA] = Q_KEY_CODE_COMMA,
- [KEY_DOT] = Q_KEY_CODE_DOT,
- [KEY_SLASH] = Q_KEY_CODE_SLASH,
- [KEY_RIGHTSHIFT] = Q_KEY_CODE_SHIFT_R,
- [KEY_LEFTALT] = Q_KEY_CODE_ALT,
- [KEY_SPACE] = Q_KEY_CODE_SPC,
- [KEY_CAPSLOCK] = Q_KEY_CODE_CAPS_LOCK,
- [KEY_F1] = Q_KEY_CODE_F1,
- [KEY_F2] = Q_KEY_CODE_F2,
- [KEY_F3] = Q_KEY_CODE_F3,
- [KEY_F4] = Q_KEY_CODE_F4,
- [KEY_F5] = Q_KEY_CODE_F5,
- [KEY_F6] = Q_KEY_CODE_F6,
- [KEY_F7] = Q_KEY_CODE_F7,
- [KEY_F8] = Q_KEY_CODE_F8,
- [KEY_F9] = Q_KEY_CODE_F9,
- [KEY_F10] = Q_KEY_CODE_F10,
- [KEY_NUMLOCK] = Q_KEY_CODE_NUM_LOCK,
- [KEY_SCROLLLOCK] = Q_KEY_CODE_SCROLL_LOCK,
- [KEY_KP0] = Q_KEY_CODE_KP_0,
- [KEY_KP1] = Q_KEY_CODE_KP_1,
- [KEY_KP2] = Q_KEY_CODE_KP_2,
- [KEY_KP3] = Q_KEY_CODE_KP_3,
- [KEY_KP4] = Q_KEY_CODE_KP_4,
- [KEY_KP5] = Q_KEY_CODE_KP_5,
- [KEY_KP6] = Q_KEY_CODE_KP_6,
- [KEY_KP7] = Q_KEY_CODE_KP_7,
- [KEY_KP8] = Q_KEY_CODE_KP_8,
- [KEY_KP9] = Q_KEY_CODE_KP_9,
- [KEY_KPMINUS] = Q_KEY_CODE_KP_SUBTRACT,
- [KEY_KPPLUS] = Q_KEY_CODE_KP_ADD,
- [KEY_KPDOT] = Q_KEY_CODE_KP_DECIMAL,
- [KEY_KPENTER] = Q_KEY_CODE_KP_ENTER,
- [KEY_KPSLASH] = Q_KEY_CODE_KP_DIVIDE,
- [KEY_KPASTERISK] = Q_KEY_CODE_KP_MULTIPLY,
- [KEY_F11] = Q_KEY_CODE_F11,
- [KEY_F12] = Q_KEY_CODE_F12,
- [KEY_RIGHTCTRL] = Q_KEY_CODE_CTRL_R,
- [KEY_SYSRQ] = Q_KEY_CODE_SYSRQ,
- [KEY_RIGHTALT] = Q_KEY_CODE_ALT_R,
- [KEY_HOME] = Q_KEY_CODE_HOME,
- [KEY_UP] = Q_KEY_CODE_UP,
- [KEY_PAGEUP] = Q_KEY_CODE_PGUP,
- [KEY_LEFT] = Q_KEY_CODE_LEFT,
- [KEY_RIGHT] = Q_KEY_CODE_RIGHT,
- [KEY_END] = Q_KEY_CODE_END,
- [KEY_DOWN] = Q_KEY_CODE_DOWN,
- [KEY_PAGEDOWN] = Q_KEY_CODE_PGDN,
- [KEY_INSERT] = Q_KEY_CODE_INSERT,
- [KEY_DELETE] = Q_KEY_CODE_DELETE,
- [KEY_LEFTMETA] = Q_KEY_CODE_META_L,
- [KEY_RIGHTMETA] = Q_KEY_CODE_META_R,
- [KEY_MENU] = Q_KEY_CODE_MENU,
-};
-
-static int qemu_input_linux_to_qcode(unsigned int lnx)
-{
- assert(lnx < KEY_CNT);
- return linux_to_qcode[lnx];
-}
-
-#define TYPE_INPUT_LINUX "input-linux"
-#define INPUT_LINUX(obj) \
- OBJECT_CHECK(InputLinux, (obj), TYPE_INPUT_LINUX)
-#define INPUT_LINUX_GET_CLASS(obj) \
- OBJECT_GET_CLASS(InputLinuxClass, (obj), TYPE_INPUT_LINUX)
-#define INPUT_LINUX_CLASS(klass) \
- OBJECT_CLASS_CHECK(InputLinuxClass, (klass), TYPE_INPUT_LINUX)
-
-typedef struct InputLinux InputLinux;
-typedef struct InputLinuxClass InputLinuxClass;
-
-struct InputLinux {
- Object parent;
-
- char *evdev;
- int fd;
- bool repeat;
- bool grab_request;
- bool grab_active;
- bool grab_all;
- bool keydown[KEY_CNT];
- int keycount;
- int wheel;
- bool initialized;
- QTAILQ_ENTRY(InputLinux) next;
-};
-
-struct InputLinuxClass {
- ObjectClass parent_class;
-};
-
-static QTAILQ_HEAD(, InputLinux) inputs = QTAILQ_HEAD_INITIALIZER(inputs);
-
-static void input_linux_toggle_grab(InputLinux *il)
-{
- intptr_t request = !il->grab_active;
- InputLinux *item;
- int rc;
-
- rc = ioctl(il->fd, EVIOCGRAB, request);
- if (rc < 0) {
- return;
- }
- il->grab_active = !il->grab_active;
-
- if (!il->grab_all) {
- return;
- }
- QTAILQ_FOREACH(item, &inputs, next) {
- if (item == il || item->grab_all) {
- /* avoid endless loops */
- continue;
- }
- if (item->grab_active != il->grab_active) {
- input_linux_toggle_grab(item);
- }
- }
-}
-
-static void input_linux_event_keyboard(void *opaque)
-{
- InputLinux *il = opaque;
- struct input_event event;
- int rc;
-
- for (;;) {
- rc = read(il->fd, &event, sizeof(event));
- if (rc != sizeof(event)) {
- if (rc < 0 && errno != EAGAIN) {
- fprintf(stderr, "%s: read: %s\n", __func__, strerror(errno));
- qemu_set_fd_handler(il->fd, NULL, NULL, NULL);
- close(il->fd);
- }
- break;
- }
-
- switch (event.type) {
- case EV_KEY:
- if (event.value > 2 || (event.value > 1 && !il->repeat)) {
- /*
- * ignore autorepeat + unknown key events
- * 0 == up, 1 == down, 2 == autorepeat, other == undefined
- */
- continue;
- }
- if (event.code >= KEY_CNT) {
- /*
- * Should not happen. But better safe than sorry,
- * and we make Coverity happy too.
- */
- continue;
- }
- /* keep track of key state */
- if (!il->keydown[event.code] && event.value) {
- il->keydown[event.code] = true;
- il->keycount++;
- }
- if (il->keydown[event.code] && !event.value) {
- il->keydown[event.code] = false;
- il->keycount--;
- }
-
- /* send event to guest when grab is active */
- if (il->grab_active) {
- int qcode = qemu_input_linux_to_qcode(event.code);
- qemu_input_event_send_key_qcode(NULL, qcode, event.value);
- }
-
- /* hotkey -> record switch request ... */
- if (il->keydown[KEY_LEFTCTRL] &&
- il->keydown[KEY_RIGHTCTRL]) {
- il->grab_request = true;
- }
-
- /*
- * ... and do the switch when all keys are lifted, so we
- * confuse neither guest nor host with keys which seem to
- * be stuck due to missing key-up events.
- */
- if (il->grab_request && !il->keycount) {
- il->grab_request = false;
- input_linux_toggle_grab(il);
- }
- break;
- }
- }
-}
-
-static void input_linux_event_mouse_button(int button)
-{
- qemu_input_queue_btn(NULL, button, true);
- qemu_input_event_sync();
- qemu_input_queue_btn(NULL, button, false);
- qemu_input_event_sync();
-}
-
-static void input_linux_event_mouse(void *opaque)
-{
- InputLinux *il = opaque;
- struct input_event event;
- int rc;
-
- for (;;) {
- rc = read(il->fd, &event, sizeof(event));
- if (rc != sizeof(event)) {
- if (rc < 0 && errno != EAGAIN) {
- fprintf(stderr, "%s: read: %s\n", __func__, strerror(errno));
- qemu_set_fd_handler(il->fd, NULL, NULL, NULL);
- close(il->fd);
- }
- break;
- }
-
- /* only send event to guest when grab is active */
- if (!il->grab_active) {
- continue;
- }
-
- switch (event.type) {
- case EV_KEY:
- switch (event.code) {
- case BTN_LEFT:
- qemu_input_queue_btn(NULL, INPUT_BUTTON_LEFT, event.value);
- break;
- case BTN_RIGHT:
- qemu_input_queue_btn(NULL, INPUT_BUTTON_RIGHT, event.value);
- break;
- case BTN_MIDDLE:
- qemu_input_queue_btn(NULL, INPUT_BUTTON_MIDDLE, event.value);
- break;
- case BTN_GEAR_UP:
- qemu_input_queue_btn(NULL, INPUT_BUTTON_WHEEL_UP, event.value);
- break;
- case BTN_GEAR_DOWN:
- qemu_input_queue_btn(NULL, INPUT_BUTTON_WHEEL_DOWN,
- event.value);
- break;
- };
- break;
- case EV_REL:
- switch (event.code) {
- case REL_X:
- qemu_input_queue_rel(NULL, INPUT_AXIS_X, event.value);
- break;
- case REL_Y:
- qemu_input_queue_rel(NULL, INPUT_AXIS_Y, event.value);
- break;
- case REL_WHEEL:
- il->wheel = event.value;
- break;
- }
- break;
- case EV_SYN:
- qemu_input_event_sync();
- if (il->wheel != 0) {
- input_linux_event_mouse_button((il->wheel > 0)
- ? INPUT_BUTTON_WHEEL_UP
- : INPUT_BUTTON_WHEEL_DOWN);
- il->wheel = 0;
- }
- break;
- }
- }
-}
-
-static void input_linux_complete(UserCreatable *uc, Error **errp)
-{
- InputLinux *il = INPUT_LINUX(uc);
- uint32_t evtmap, relmap, absmap;
- int rc, ver;
-
- if (!il->evdev) {
- error_setg(errp, "no input device specified");
- return;
- }
-
- il->fd = open(il->evdev, O_RDWR);
- if (il->fd < 0) {
- error_setg_file_open(errp, errno, il->evdev);
- return;
- }
- qemu_set_nonblock(il->fd);
-
- rc = ioctl(il->fd, EVIOCGVERSION, &ver);
- if (rc < 0) {
- error_setg(errp, "%s: is not an evdev device", il->evdev);
- goto err_close;
- }
-
- rc = ioctl(il->fd, EVIOCGBIT(0, sizeof(evtmap)), &evtmap);
- if (rc < 0) {
- error_setg(errp, "%s: failed to read event bits", il->evdev);
- goto err_close;
- }
-
- if (evtmap & (1 << EV_REL)) {
- rc = ioctl(il->fd, EVIOCGBIT(EV_REL, sizeof(relmap)), &relmap);
- if (rc < 0) {
- relmap = 0;
- }
- }
-
- if (evtmap & (1 << EV_ABS)) {
- ioctl(il->fd, EVIOCGBIT(EV_ABS, sizeof(absmap)), &absmap);
- if (rc < 0) {
- absmap = 0;
- }
- }
-
- if ((evtmap & (1 << EV_REL)) &&
- (relmap & (1 << REL_X))) {
- /* has relative x axis -> assume mouse */
- qemu_set_fd_handler(il->fd, input_linux_event_mouse, NULL, il);
- } else if ((evtmap & (1 << EV_ABS)) &&
- (absmap & (1 << ABS_X))) {
- /* has absolute x axis -> not supported */
- error_setg(errp, "tablet/touchscreen not supported");
- goto err_close;
- } else if (evtmap & (1 << EV_KEY)) {
- /* has keys/buttons (and no x axis) -> assume keyboard */
- qemu_set_fd_handler(il->fd, input_linux_event_keyboard, NULL, il);
- } else {
- /* Huh? What is this? */
- error_setg(errp, "unknown kind of input device");
- goto err_close;
- }
- input_linux_toggle_grab(il);
- QTAILQ_INSERT_TAIL(&inputs, il, next);
- il->initialized = true;
- return;
-
-err_close:
- close(il->fd);
- return;
-}
-
-static void input_linux_instance_finalize(Object *obj)
-{
- InputLinux *il = INPUT_LINUX(obj);
-
- if (il->initialized) {
- QTAILQ_REMOVE(&inputs, il, next);
- close(il->fd);
- }
- g_free(il->evdev);
-}
-
-static char *input_linux_get_evdev(Object *obj, Error **errp)
-{
- InputLinux *il = INPUT_LINUX(obj);
-
- return g_strdup(il->evdev);
-}
-
-static void input_linux_set_evdev(Object *obj, const char *value,
- Error **errp)
-{
- InputLinux *il = INPUT_LINUX(obj);
-
- if (il->evdev) {
- error_setg(errp, "evdev property already set");
- return;
- }
- il->evdev = g_strdup(value);
-}
-
-static bool input_linux_get_grab_all(Object *obj, Error **errp)
-{
- InputLinux *il = INPUT_LINUX(obj);
-
- return il->grab_all;
-}
-
-static void input_linux_set_grab_all(Object *obj, bool value,
- Error **errp)
-{
- InputLinux *il = INPUT_LINUX(obj);
-
- il->grab_all = value;
-}
-
-static bool input_linux_get_repeat(Object *obj, Error **errp)
-{
- InputLinux *il = INPUT_LINUX(obj);
-
- return il->repeat;
-}
-
-static void input_linux_set_repeat(Object *obj, bool value,
- Error **errp)
-{
- InputLinux *il = INPUT_LINUX(obj);
-
- il->repeat = value;
-}
-
-static void input_linux_instance_init(Object *obj)
-{
- object_property_add_str(obj, "evdev",
- input_linux_get_evdev,
- input_linux_set_evdev, NULL);
- object_property_add_bool(obj, "grab_all",
- input_linux_get_grab_all,
- input_linux_set_grab_all, NULL);
- object_property_add_bool(obj, "repeat",
- input_linux_get_repeat,
- input_linux_set_repeat, NULL);
-}
-
-static void input_linux_class_init(ObjectClass *oc, void *data)
-{
- UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
-
- ucc->complete = input_linux_complete;
-}
-
-static const TypeInfo input_linux_info = {
- .name = TYPE_INPUT_LINUX,
- .parent = TYPE_OBJECT,
- .class_size = sizeof(InputLinuxClass),
- .class_init = input_linux_class_init,
- .instance_size = sizeof(InputLinux),
- .instance_init = input_linux_instance_init,
- .instance_finalize = input_linux_instance_finalize,
- .interfaces = (InterfaceInfo[]) {
- { TYPE_USER_CREATABLE },
- { }
- }
-};
-
-static void register_types(void)
-{
- type_register_static(&input_linux_info);
-}
-
-type_init(register_types);
diff --git a/qemu/ui/input.c b/qemu/ui/input.c
deleted file mode 100644
index ed88cda6d..000000000
--- a/qemu/ui/input.c
+++ /dev/null
@@ -1,574 +0,0 @@
-#include "qemu/osdep.h"
-#include "hw/qdev.h"
-#include "sysemu/sysemu.h"
-#include "qapi-types.h"
-#include "qemu/error-report.h"
-#include "qmp-commands.h"
-#include "trace.h"
-#include "ui/input.h"
-#include "ui/console.h"
-#include "sysemu/replay.h"
-
-struct QemuInputHandlerState {
- DeviceState *dev;
- QemuInputHandler *handler;
- int id;
- int events;
- QemuConsole *con;
- QTAILQ_ENTRY(QemuInputHandlerState) node;
-};
-
-typedef struct QemuInputEventQueue QemuInputEventQueue;
-struct QemuInputEventQueue {
- enum {
- QEMU_INPUT_QUEUE_DELAY = 1,
- QEMU_INPUT_QUEUE_EVENT,
- QEMU_INPUT_QUEUE_SYNC,
- } type;
- QEMUTimer *timer;
- uint32_t delay_ms;
- QemuConsole *src;
- InputEvent *evt;
- QTAILQ_ENTRY(QemuInputEventQueue) node;
-};
-
-static QTAILQ_HEAD(, QemuInputHandlerState) handlers =
- QTAILQ_HEAD_INITIALIZER(handlers);
-static NotifierList mouse_mode_notifiers =
- NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers);
-
-static QTAILQ_HEAD(QemuInputEventQueueHead, QemuInputEventQueue) kbd_queue =
- QTAILQ_HEAD_INITIALIZER(kbd_queue);
-static QEMUTimer *kbd_timer;
-static uint32_t kbd_default_delay_ms = 10;
-
-QemuInputHandlerState *qemu_input_handler_register(DeviceState *dev,
- QemuInputHandler *handler)
-{
- QemuInputHandlerState *s = g_new0(QemuInputHandlerState, 1);
- static int id = 1;
-
- s->dev = dev;
- s->handler = handler;
- s->id = id++;
- QTAILQ_INSERT_TAIL(&handlers, s, node);
-
- qemu_input_check_mode_change();
- return s;
-}
-
-void qemu_input_handler_activate(QemuInputHandlerState *s)
-{
- QTAILQ_REMOVE(&handlers, s, node);
- QTAILQ_INSERT_HEAD(&handlers, s, node);
- qemu_input_check_mode_change();
-}
-
-void qemu_input_handler_deactivate(QemuInputHandlerState *s)
-{
- QTAILQ_REMOVE(&handlers, s, node);
- QTAILQ_INSERT_TAIL(&handlers, s, node);
- qemu_input_check_mode_change();
-}
-
-void qemu_input_handler_unregister(QemuInputHandlerState *s)
-{
- QTAILQ_REMOVE(&handlers, s, node);
- g_free(s);
- qemu_input_check_mode_change();
-}
-
-void qemu_input_handler_bind(QemuInputHandlerState *s,
- const char *device_id, int head,
- Error **errp)
-{
- QemuConsole *con;
- Error *err = NULL;
-
- con = qemu_console_lookup_by_device_name(device_id, head, &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- s->con = con;
-}
-
-static QemuInputHandlerState*
-qemu_input_find_handler(uint32_t mask, QemuConsole *con)
-{
- QemuInputHandlerState *s;
-
- QTAILQ_FOREACH(s, &handlers, node) {
- if (s->con == NULL || s->con != con) {
- continue;
- }
- if (mask & s->handler->mask) {
- return s;
- }
- }
-
- QTAILQ_FOREACH(s, &handlers, node) {
- if (s->con != NULL) {
- continue;
- }
- if (mask & s->handler->mask) {
- return s;
- }
- }
- return NULL;
-}
-
-void qmp_input_send_event(bool has_device, const char *device,
- bool has_head, int64_t head,
- InputEventList *events, Error **errp)
-{
- InputEventList *e;
- QemuConsole *con;
- Error *err = NULL;
-
- con = NULL;
- if (has_device) {
- if (!has_head) {
- head = 0;
- }
- con = qemu_console_lookup_by_device_name(device, head, &err);
- if (err) {
- error_propagate(errp, err);
- return;
- }
- }
-
- if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
- error_setg(errp, "VM not running");
- return;
- }
-
- for (e = events; e != NULL; e = e->next) {
- InputEvent *event = e->value;
-
- if (!qemu_input_find_handler(1 << event->type, con)) {
- error_setg(errp, "Input handler not found for "
- "event type %s",
- InputEventKind_lookup[event->type]);
- return;
- }
- }
-
- for (e = events; e != NULL; e = e->next) {
- InputEvent *event = e->value;
-
- qemu_input_event_send(con, event);
- }
-
- qemu_input_event_sync();
-}
-
-static void qemu_input_transform_abs_rotate(InputEvent *evt)
-{
- InputMoveEvent *move = evt->u.abs.data;
- switch (graphic_rotate) {
- case 90:
- if (move->axis == INPUT_AXIS_X) {
- move->axis = INPUT_AXIS_Y;
- } else if (move->axis == INPUT_AXIS_Y) {
- move->axis = INPUT_AXIS_X;
- move->value = INPUT_EVENT_ABS_SIZE - 1 - move->value;
- }
- break;
- case 180:
- move->value = INPUT_EVENT_ABS_SIZE - 1 - move->value;
- break;
- case 270:
- if (move->axis == INPUT_AXIS_X) {
- move->axis = INPUT_AXIS_Y;
- move->value = INPUT_EVENT_ABS_SIZE - 1 - move->value;
- } else if (move->axis == INPUT_AXIS_Y) {
- move->axis = INPUT_AXIS_X;
- }
- break;
- }
-}
-
-static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt)
-{
- const char *name;
- int qcode, idx = -1;
- InputKeyEvent *key;
- InputBtnEvent *btn;
- InputMoveEvent *move;
-
- if (src) {
- idx = qemu_console_get_index(src);
- }
- switch (evt->type) {
- case INPUT_EVENT_KIND_KEY:
- key = evt->u.key.data;
- switch (key->key->type) {
- case KEY_VALUE_KIND_NUMBER:
- qcode = qemu_input_key_number_to_qcode(key->key->u.number.data);
- name = QKeyCode_lookup[qcode];
- trace_input_event_key_number(idx, key->key->u.number.data,
- name, key->down);
- break;
- case KEY_VALUE_KIND_QCODE:
- name = QKeyCode_lookup[key->key->u.qcode.data];
- trace_input_event_key_qcode(idx, name, key->down);
- break;
- case KEY_VALUE_KIND__MAX:
- /* keep gcc happy */
- break;
- }
- break;
- case INPUT_EVENT_KIND_BTN:
- btn = evt->u.btn.data;
- name = InputButton_lookup[btn->button];
- trace_input_event_btn(idx, name, btn->down);
- break;
- case INPUT_EVENT_KIND_REL:
- move = evt->u.rel.data;
- name = InputAxis_lookup[move->axis];
- trace_input_event_rel(idx, name, move->value);
- break;
- case INPUT_EVENT_KIND_ABS:
- move = evt->u.abs.data;
- name = InputAxis_lookup[move->axis];
- trace_input_event_abs(idx, name, move->value);
- break;
- case INPUT_EVENT_KIND__MAX:
- /* keep gcc happy */
- break;
- }
-}
-
-static void qemu_input_queue_process(void *opaque)
-{
- struct QemuInputEventQueueHead *queue = opaque;
- QemuInputEventQueue *item;
-
- g_assert(!QTAILQ_EMPTY(queue));
- item = QTAILQ_FIRST(queue);
- g_assert(item->type == QEMU_INPUT_QUEUE_DELAY);
- QTAILQ_REMOVE(queue, item, node);
- g_free(item);
-
- while (!QTAILQ_EMPTY(queue)) {
- item = QTAILQ_FIRST(queue);
- switch (item->type) {
- case QEMU_INPUT_QUEUE_DELAY:
- timer_mod(item->timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL)
- + item->delay_ms);
- return;
- case QEMU_INPUT_QUEUE_EVENT:
- qemu_input_event_send(item->src, item->evt);
- qapi_free_InputEvent(item->evt);
- break;
- case QEMU_INPUT_QUEUE_SYNC:
- qemu_input_event_sync();
- break;
- }
- QTAILQ_REMOVE(queue, item, node);
- g_free(item);
- }
-}
-
-static void qemu_input_queue_delay(struct QemuInputEventQueueHead *queue,
- QEMUTimer *timer, uint32_t delay_ms)
-{
- QemuInputEventQueue *item = g_new0(QemuInputEventQueue, 1);
- bool start_timer = QTAILQ_EMPTY(queue);
-
- item->type = QEMU_INPUT_QUEUE_DELAY;
- item->delay_ms = delay_ms;
- item->timer = timer;
- QTAILQ_INSERT_TAIL(queue, item, node);
-
- if (start_timer) {
- timer_mod(item->timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL)
- + item->delay_ms);
- }
-}
-
-static void qemu_input_queue_event(struct QemuInputEventQueueHead *queue,
- QemuConsole *src, InputEvent *evt)
-{
- QemuInputEventQueue *item = g_new0(QemuInputEventQueue, 1);
-
- item->type = QEMU_INPUT_QUEUE_EVENT;
- item->src = src;
- item->evt = evt;
- QTAILQ_INSERT_TAIL(queue, item, node);
-}
-
-static void qemu_input_queue_sync(struct QemuInputEventQueueHead *queue)
-{
- QemuInputEventQueue *item = g_new0(QemuInputEventQueue, 1);
-
- item->type = QEMU_INPUT_QUEUE_SYNC;
- QTAILQ_INSERT_TAIL(queue, item, node);
-}
-
-void qemu_input_event_send_impl(QemuConsole *src, InputEvent *evt)
-{
- QemuInputHandlerState *s;
-
- qemu_input_event_trace(src, evt);
-
- /* pre processing */
- if (graphic_rotate && (evt->type == INPUT_EVENT_KIND_ABS)) {
- qemu_input_transform_abs_rotate(evt);
- }
-
- /* send event */
- s = qemu_input_find_handler(1 << evt->type, src);
- if (!s) {
- return;
- }
- s->handler->event(s->dev, src, evt);
- s->events++;
-}
-
-void qemu_input_event_send(QemuConsole *src, InputEvent *evt)
-{
- if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
- return;
- }
-
- replay_input_event(src, evt);
-}
-
-void qemu_input_event_sync_impl(void)
-{
- QemuInputHandlerState *s;
-
- trace_input_event_sync();
-
- QTAILQ_FOREACH(s, &handlers, node) {
- if (!s->events) {
- continue;
- }
- if (s->handler->sync) {
- s->handler->sync(s->dev);
- }
- s->events = 0;
- }
-}
-
-void qemu_input_event_sync(void)
-{
- if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
- return;
- }
-
- replay_input_sync_event();
-}
-
-InputEvent *qemu_input_event_new_key(KeyValue *key, bool down)
-{
- InputEvent *evt = g_new0(InputEvent, 1);
- evt->u.key.data = g_new0(InputKeyEvent, 1);
- evt->type = INPUT_EVENT_KIND_KEY;
- evt->u.key.data->key = key;
- evt->u.key.data->down = down;
- return evt;
-}
-
-void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down)
-{
- InputEvent *evt;
- evt = qemu_input_event_new_key(key, down);
- if (QTAILQ_EMPTY(&kbd_queue)) {
- qemu_input_event_send(src, evt);
- qemu_input_event_sync();
- qapi_free_InputEvent(evt);
- } else {
- qemu_input_queue_event(&kbd_queue, src, evt);
- qemu_input_queue_sync(&kbd_queue);
- }
-}
-
-void qemu_input_event_send_key_number(QemuConsole *src, int num, bool down)
-{
- KeyValue *key = g_new0(KeyValue, 1);
- key->type = KEY_VALUE_KIND_NUMBER;
- key->u.number.data = num;
- qemu_input_event_send_key(src, key, down);
-}
-
-void qemu_input_event_send_key_qcode(QemuConsole *src, QKeyCode q, bool down)
-{
- KeyValue *key = g_new0(KeyValue, 1);
- key->type = KEY_VALUE_KIND_QCODE;
- key->u.qcode.data = q;
- qemu_input_event_send_key(src, key, down);
-}
-
-void qemu_input_event_send_key_delay(uint32_t delay_ms)
-{
- if (!kbd_timer) {
- kbd_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, qemu_input_queue_process,
- &kbd_queue);
- }
- qemu_input_queue_delay(&kbd_queue, kbd_timer,
- delay_ms ? delay_ms : kbd_default_delay_ms);
-}
-
-InputEvent *qemu_input_event_new_btn(InputButton btn, bool down)
-{
- InputEvent *evt = g_new0(InputEvent, 1);
- evt->u.btn.data = g_new0(InputBtnEvent, 1);
- evt->type = INPUT_EVENT_KIND_BTN;
- evt->u.btn.data->button = btn;
- evt->u.btn.data->down = down;
- return evt;
-}
-
-void qemu_input_queue_btn(QemuConsole *src, InputButton btn, bool down)
-{
- InputEvent *evt;
- evt = qemu_input_event_new_btn(btn, down);
- qemu_input_event_send(src, evt);
- qapi_free_InputEvent(evt);
-}
-
-void qemu_input_update_buttons(QemuConsole *src, uint32_t *button_map,
- uint32_t button_old, uint32_t button_new)
-{
- InputButton btn;
- uint32_t mask;
-
- for (btn = 0; btn < INPUT_BUTTON__MAX; btn++) {
- mask = button_map[btn];
- if ((button_old & mask) == (button_new & mask)) {
- continue;
- }
- qemu_input_queue_btn(src, btn, button_new & mask);
- }
-}
-
-bool qemu_input_is_absolute(void)
-{
- QemuInputHandlerState *s;
-
- s = qemu_input_find_handler(INPUT_EVENT_MASK_REL | INPUT_EVENT_MASK_ABS,
- NULL);
- return (s != NULL) && (s->handler->mask & INPUT_EVENT_MASK_ABS);
-}
-
-int qemu_input_scale_axis(int value, int size_in, int size_out)
-{
- if (size_in < 2) {
- return size_out / 2;
- }
- return (int64_t)value * (size_out - 1) / (size_in - 1);
-}
-
-InputEvent *qemu_input_event_new_move(InputEventKind kind,
- InputAxis axis, int value)
-{
- InputEvent *evt = g_new0(InputEvent, 1);
- InputMoveEvent *move = g_new0(InputMoveEvent, 1);
-
- evt->type = kind;
- evt->u.rel.data = move; /* evt->u.rel is the same as evt->u.abs */
- move->axis = axis;
- move->value = value;
- return evt;
-}
-
-void qemu_input_queue_rel(QemuConsole *src, InputAxis axis, int value)
-{
- InputEvent *evt;
- evt = qemu_input_event_new_move(INPUT_EVENT_KIND_REL, axis, value);
- qemu_input_event_send(src, evt);
- qapi_free_InputEvent(evt);
-}
-
-void qemu_input_queue_abs(QemuConsole *src, InputAxis axis, int value, int size)
-{
- InputEvent *evt;
- int scaled = qemu_input_scale_axis(value, size, INPUT_EVENT_ABS_SIZE);
- evt = qemu_input_event_new_move(INPUT_EVENT_KIND_ABS, axis, scaled);
- qemu_input_event_send(src, evt);
- qapi_free_InputEvent(evt);
-}
-
-void qemu_input_check_mode_change(void)
-{
- static int current_is_absolute;
- int is_absolute;
-
- is_absolute = qemu_input_is_absolute();
-
- if (is_absolute != current_is_absolute) {
- trace_input_mouse_mode(is_absolute);
- notifier_list_notify(&mouse_mode_notifiers, NULL);
- }
-
- current_is_absolute = is_absolute;
-}
-
-void qemu_add_mouse_mode_change_notifier(Notifier *notify)
-{
- notifier_list_add(&mouse_mode_notifiers, notify);
-}
-
-void qemu_remove_mouse_mode_change_notifier(Notifier *notify)
-{
- notifier_remove(notify);
-}
-
-MouseInfoList *qmp_query_mice(Error **errp)
-{
- MouseInfoList *mice_list = NULL;
- MouseInfoList *info;
- QemuInputHandlerState *s;
- bool current = true;
-
- QTAILQ_FOREACH(s, &handlers, node) {
- if (!(s->handler->mask &
- (INPUT_EVENT_MASK_REL | INPUT_EVENT_MASK_ABS))) {
- continue;
- }
-
- info = g_new0(MouseInfoList, 1);
- info->value = g_new0(MouseInfo, 1);
- info->value->index = s->id;
- info->value->name = g_strdup(s->handler->name);
- info->value->absolute = s->handler->mask & INPUT_EVENT_MASK_ABS;
- info->value->current = current;
-
- current = false;
- info->next = mice_list;
- mice_list = info;
- }
-
- return mice_list;
-}
-
-void hmp_mouse_set(Monitor *mon, const QDict *qdict)
-{
- QemuInputHandlerState *s;
- int index = qdict_get_int(qdict, "index");
- int found = 0;
-
- QTAILQ_FOREACH(s, &handlers, node) {
- if (s->id != index) {
- continue;
- }
- if (!(s->handler->mask & (INPUT_EVENT_MASK_REL |
- INPUT_EVENT_MASK_ABS))) {
- error_report("Input device '%s' is not a mouse", s->handler->name);
- return;
- }
- found = 1;
- qemu_input_handler_activate(s);
- break;
- }
-
- if (!found) {
- error_report("Mouse at index '%d' not found", index);
- }
-
- qemu_input_check_mode_change();
-}
diff --git a/qemu/ui/keymaps.c b/qemu/ui/keymaps.c
deleted file mode 100644
index 8899a0b31..000000000
--- a/qemu/ui/keymaps.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * QEMU keysym to keycode conversion using rdesktop keymaps
- *
- * Copyright (c) 2004 Johannes Schindelin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "keymaps.h"
-#include "sysemu/sysemu.h"
-
-static int get_keysym(const name2keysym_t *table,
- const char *name)
-{
- const name2keysym_t *p;
- for(p = table; p->name != NULL; p++) {
- if (!strcmp(p->name, name)) {
- return p->keysym;
- }
- }
- if (name[0] == 'U' && strlen(name) == 5) { /* try unicode Uxxxx */
- char *end;
- int ret = (int)strtoul(name + 1, &end, 16);
- if (*end == '\0' && ret > 0) {
- return ret;
- }
- }
- return 0;
-}
-
-
-static void add_to_key_range(struct key_range **krp, int code) {
- struct key_range *kr;
- for (kr = *krp; kr; kr = kr->next) {
- if (code >= kr->start && code <= kr->end) {
- break;
- }
- if (code == kr->start - 1) {
- kr->start--;
- break;
- }
- if (code == kr->end + 1) {
- kr->end++;
- break;
- }
- }
- if (kr == NULL) {
- kr = g_malloc0(sizeof(*kr));
- kr->start = kr->end = code;
- kr->next = *krp;
- *krp = kr;
- }
-}
-
-static void add_keysym(char *line, int keysym, int keycode, kbd_layout_t *k) {
- if (keysym < MAX_NORMAL_KEYCODE) {
- /* fprintf(stderr,"Setting keysym %s (%d) to %d\n",
- line, keysym, keycode); */
- k->keysym2keycode[keysym] = keycode;
- } else {
- if (k->extra_count >= MAX_EXTRA_COUNT) {
- fprintf(stderr, "Warning: Could not assign keysym %s (0x%x)"
- " because of memory constraints.\n", line, keysym);
- } else {
-#if 0
- fprintf(stderr, "Setting %d: %d,%d\n",
- k->extra_count, keysym, keycode);
-#endif
- k->keysym2keycode_extra[k->extra_count].
- keysym = keysym;
- k->keysym2keycode_extra[k->extra_count].
- keycode = keycode;
- k->extra_count++;
- }
- }
-}
-
-static kbd_layout_t *parse_keyboard_layout(const name2keysym_t *table,
- const char *language,
- kbd_layout_t *k)
-{
- FILE *f;
- char * filename;
- char line[1024];
- int len;
-
- filename = qemu_find_file(QEMU_FILE_TYPE_KEYMAP, language);
- f = filename ? fopen(filename, "r") : NULL;
- g_free(filename);
- if (!f) {
- fprintf(stderr, "Could not read keymap file: '%s'\n", language);
- return NULL;
- }
-
- if (!k) {
- k = g_new0(kbd_layout_t, 1);
- }
-
- for(;;) {
- if (fgets(line, 1024, f) == NULL) {
- break;
- }
- len = strlen(line);
- if (len > 0 && line[len - 1] == '\n') {
- line[len - 1] = '\0';
- }
- if (line[0] == '#') {
- continue;
- }
- if (!strncmp(line, "map ", 4)) {
- continue;
- }
- if (!strncmp(line, "include ", 8)) {
- parse_keyboard_layout(table, line + 8, k);
- } else {
- char *end_of_keysym = line;
- while (*end_of_keysym != 0 && *end_of_keysym != ' ') {
- end_of_keysym++;
- }
- if (*end_of_keysym) {
- int keysym;
- *end_of_keysym = 0;
- keysym = get_keysym(table, line);
- if (keysym == 0) {
- /* fprintf(stderr, "Warning: unknown keysym %s\n", line);*/
- } else {
- const char *rest = end_of_keysym + 1;
- int keycode = strtol(rest, NULL, 0);
-
- if (strstr(rest, "numlock")) {
- add_to_key_range(&k->keypad_range, keycode);
- add_to_key_range(&k->numlock_range, keysym);
- /* fprintf(stderr, "keypad keysym %04x keycode %d\n",
- keysym, keycode); */
- }
-
- if (strstr(rest, "shift")) {
- keycode |= SCANCODE_SHIFT;
- }
- if (strstr(rest, "altgr")) {
- keycode |= SCANCODE_ALTGR;
- }
- if (strstr(rest, "ctrl")) {
- keycode |= SCANCODE_CTRL;
- }
-
- add_keysym(line, keysym, keycode, k);
-
- if (strstr(rest, "addupper")) {
- char *c;
- for (c = line; *c; c++) {
- *c = qemu_toupper(*c);
- }
- keysym = get_keysym(table, line);
- if (keysym) {
- add_keysym(line, keysym,
- keycode | SCANCODE_SHIFT, k);
- }
- }
- }
- }
- }
- }
- fclose(f);
- return k;
-}
-
-
-void *init_keyboard_layout(const name2keysym_t *table, const char *language)
-{
- return parse_keyboard_layout(table, language, NULL);
-}
-
-
-int keysym2scancode(void *kbd_layout, int keysym)
-{
- kbd_layout_t *k = kbd_layout;
- if (keysym < MAX_NORMAL_KEYCODE) {
- if (k->keysym2keycode[keysym] == 0) {
- fprintf(stderr, "Warning: no scancode found for keysym %d\n",
- keysym);
- }
- return k->keysym2keycode[keysym];
- } else {
- int i;
-#ifdef XK_ISO_Left_Tab
- if (keysym == XK_ISO_Left_Tab) {
- keysym = XK_Tab;
- }
-#endif
- for (i = 0; i < k->extra_count; i++) {
- if (k->keysym2keycode_extra[i].keysym == keysym) {
- return k->keysym2keycode_extra[i].keycode;
- }
- }
- }
- return 0;
-}
-
-int keycode_is_keypad(void *kbd_layout, int keycode)
-{
- kbd_layout_t *k = kbd_layout;
- struct key_range *kr;
-
- for (kr = k->keypad_range; kr; kr = kr->next) {
- if (keycode >= kr->start && keycode <= kr->end) {
- return 1;
- }
- }
- return 0;
-}
-
-int keysym_is_numlock(void *kbd_layout, int keysym)
-{
- kbd_layout_t *k = kbd_layout;
- struct key_range *kr;
-
- for (kr = k->numlock_range; kr; kr = kr->next) {
- if (keysym >= kr->start && keysym <= kr->end) {
- return 1;
- }
- }
- return 0;
-}
diff --git a/qemu/ui/keymaps.h b/qemu/ui/keymaps.h
deleted file mode 100644
index a7600d575..000000000
--- a/qemu/ui/keymaps.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * QEMU keysym to keycode conversion using rdesktop keymaps
- *
- * Copyright (c) 2004 Johannes Schindelin
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef __QEMU_KEYMAPS_H__
-#define __QEMU_KEYMAPS_H__
-
-#include "qemu-common.h"
-
-typedef struct {
- const char* name;
- int keysym;
-} name2keysym_t;
-
-struct key_range {
- int start;
- int end;
- struct key_range *next;
-};
-
-#define MAX_NORMAL_KEYCODE 512
-#define MAX_EXTRA_COUNT 256
-typedef struct {
- uint16_t keysym2keycode[MAX_NORMAL_KEYCODE];
- struct {
- int keysym;
- uint16_t keycode;
- } keysym2keycode_extra[MAX_EXTRA_COUNT];
- int extra_count;
- struct key_range *keypad_range;
- struct key_range *numlock_range;
-} kbd_layout_t;
-
-/* scancode without modifiers */
-#define SCANCODE_KEYMASK 0xff
-/* scancode without grey or up bit */
-#define SCANCODE_KEYCODEMASK 0x7f
-
-/* "grey" keys will usually need a 0xe0 prefix */
-#define SCANCODE_GREY 0x80
-#define SCANCODE_EMUL0 0xE0
-/* "up" flag */
-#define SCANCODE_UP 0x80
-
-/* Additional modifiers to use if not catched another way. */
-#define SCANCODE_SHIFT 0x100
-#define SCANCODE_CTRL 0x200
-#define SCANCODE_ALT 0x400
-#define SCANCODE_ALTGR 0x800
-
-
-void *init_keyboard_layout(const name2keysym_t *table, const char *language);
-int keysym2scancode(void *kbd_layout, int keysym);
-int keycode_is_keypad(void *kbd_layout, int keycode);
-int keysym_is_numlock(void *kbd_layout, int keysym);
-
-#endif /* __QEMU_KEYMAPS_H__ */
diff --git a/qemu/ui/qemu-pixman.c b/qemu/ui/qemu-pixman.c
deleted file mode 100644
index c9f8dce7f..000000000
--- a/qemu/ui/qemu-pixman.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "ui/console.h"
-
-PixelFormat qemu_pixelformat_from_pixman(pixman_format_code_t format)
-{
- PixelFormat pf;
- uint8_t bpp;
-
- bpp = pf.bits_per_pixel = PIXMAN_FORMAT_BPP(format);
- pf.bytes_per_pixel = PIXMAN_FORMAT_BPP(format) / 8;
- pf.depth = PIXMAN_FORMAT_DEPTH(format);
-
- pf.abits = PIXMAN_FORMAT_A(format);
- pf.rbits = PIXMAN_FORMAT_R(format);
- pf.gbits = PIXMAN_FORMAT_G(format);
- pf.bbits = PIXMAN_FORMAT_B(format);
-
- switch (PIXMAN_FORMAT_TYPE(format)) {
- case PIXMAN_TYPE_ARGB:
- pf.ashift = pf.bbits + pf.gbits + pf.rbits;
- pf.rshift = pf.bbits + pf.gbits;
- pf.gshift = pf.bbits;
- pf.bshift = 0;
- break;
- case PIXMAN_TYPE_ABGR:
- pf.ashift = pf.rbits + pf.gbits + pf.bbits;
- pf.bshift = pf.rbits + pf.gbits;
- pf.gshift = pf.rbits;
- pf.rshift = 0;
- break;
- case PIXMAN_TYPE_BGRA:
- pf.bshift = bpp - pf.bbits;
- pf.gshift = bpp - (pf.bbits + pf.gbits);
- pf.rshift = bpp - (pf.bbits + pf.gbits + pf.rbits);
- pf.ashift = 0;
- break;
- case PIXMAN_TYPE_RGBA:
- pf.rshift = bpp - pf.rbits;
- pf.gshift = bpp - (pf.rbits + pf.gbits);
- pf.bshift = bpp - (pf.rbits + pf.gbits + pf.bbits);
- pf.ashift = 0;
- break;
- default:
- g_assert_not_reached();
- break;
- }
-
- pf.amax = (1 << pf.abits) - 1;
- pf.rmax = (1 << pf.rbits) - 1;
- pf.gmax = (1 << pf.gbits) - 1;
- pf.bmax = (1 << pf.bbits) - 1;
- pf.amask = pf.amax << pf.ashift;
- pf.rmask = pf.rmax << pf.rshift;
- pf.gmask = pf.gmax << pf.gshift;
- pf.bmask = pf.bmax << pf.bshift;
-
- return pf;
-}
-
-pixman_format_code_t qemu_default_pixman_format(int bpp, bool native_endian)
-{
- if (native_endian) {
- switch (bpp) {
- case 15:
- return PIXMAN_x1r5g5b5;
- case 16:
- return PIXMAN_r5g6b5;
- case 24:
- return PIXMAN_r8g8b8;
- case 32:
- return PIXMAN_x8r8g8b8;
- }
- } else {
- switch (bpp) {
- case 24:
- return PIXMAN_b8g8r8;
- case 32:
- return PIXMAN_b8g8r8x8;
- break;
- }
- }
- return 0;
-}
-
-int qemu_pixman_get_type(int rshift, int gshift, int bshift)
-{
- int type = PIXMAN_TYPE_OTHER;
-
- if (rshift > gshift && gshift > bshift) {
- if (bshift == 0) {
- type = PIXMAN_TYPE_ARGB;
- } else {
-#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0, 21, 8)
- type = PIXMAN_TYPE_RGBA;
-#endif
- }
- } else if (rshift < gshift && gshift < bshift) {
- if (rshift == 0) {
- type = PIXMAN_TYPE_ABGR;
- } else {
-#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0, 16, 0)
- type = PIXMAN_TYPE_BGRA;
-#endif
- }
- }
- return type;
-}
-
-pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf)
-{
- pixman_format_code_t format;
- int type;
-
- type = qemu_pixman_get_type(pf->rshift, pf->gshift, pf->bshift);
- format = PIXMAN_FORMAT(pf->bits_per_pixel, type,
- pf->abits, pf->rbits, pf->gbits, pf->bbits);
- if (!pixman_format_supported_source(format)) {
- return 0;
- }
- return format;
-}
-
-/*
- * Return true for known-good pixman conversions.
- *
- * UIs using pixman for format conversion can hook this into
- * DisplayChangeListenerOps->dpy_gfx_check_format
- */
-bool qemu_pixman_check_format(DisplayChangeListener *dcl,
- pixman_format_code_t format)
-{
- switch (format) {
- /* 32 bpp */
- case PIXMAN_x8r8g8b8:
- case PIXMAN_a8r8g8b8:
- case PIXMAN_b8g8r8x8:
- case PIXMAN_b8g8r8a8:
- /* 24 bpp */
- case PIXMAN_r8g8b8:
- case PIXMAN_b8g8r8:
- /* 16 bpp */
- case PIXMAN_x1r5g5b5:
- case PIXMAN_r5g6b5:
- return true;
- default:
- return false;
- }
-}
-
-pixman_image_t *qemu_pixman_linebuf_create(pixman_format_code_t format,
- int width)
-{
- pixman_image_t *image = pixman_image_create_bits(format, width, 1, NULL, 0);
- assert(image != NULL);
- return image;
-}
-
-/* fill linebuf from framebuffer */
-void qemu_pixman_linebuf_fill(pixman_image_t *linebuf, pixman_image_t *fb,
- int width, int x, int y)
-{
- pixman_image_composite(PIXMAN_OP_SRC, fb, NULL, linebuf,
- x, y, 0, 0, 0, 0, width, 1);
-}
-
-/* copy linebuf to framebuffer */
-void qemu_pixman_linebuf_copy(pixman_image_t *fb, int width, int x, int y,
- pixman_image_t *linebuf)
-{
- pixman_image_composite(PIXMAN_OP_SRC, linebuf, NULL, fb,
- 0, 0, 0, 0, x, y, width, 1);
-}
-
-pixman_image_t *qemu_pixman_mirror_create(pixman_format_code_t format,
- pixman_image_t *image)
-{
- pixman_image_t *mirror;
-
- mirror = pixman_image_create_bits(format,
- pixman_image_get_width(image),
- pixman_image_get_height(image),
- NULL,
- pixman_image_get_stride(image));
- return mirror;
-}
-
-void qemu_pixman_image_unref(pixman_image_t *image)
-{
- if (image == NULL) {
- return;
- }
- pixman_image_unref(image);
-}
-
-pixman_color_t qemu_pixman_color(PixelFormat *pf, uint32_t color)
-{
- pixman_color_t c;
-
- c.red = ((color & pf->rmask) >> pf->rshift) << (16 - pf->rbits);
- c.green = ((color & pf->gmask) >> pf->gshift) << (16 - pf->gbits);
- c.blue = ((color & pf->bmask) >> pf->bshift) << (16 - pf->bbits);
- c.alpha = ((color & pf->amask) >> pf->ashift) << (16 - pf->abits);
- return c;
-}
-
-pixman_image_t *qemu_pixman_glyph_from_vgafont(int height, const uint8_t *font,
- unsigned int ch)
-{
- pixman_image_t *glyph;
- uint8_t *data;
- bool bit;
- int x, y;
-
- glyph = pixman_image_create_bits(PIXMAN_a8, 8, height,
- NULL, 0);
- data = (uint8_t *)pixman_image_get_data(glyph);
-
- font += height * ch;
- for (y = 0; y < height; y++, font++) {
- for (x = 0; x < 8; x++, data++) {
- bit = (*font) & (1 << (7-x));
- *data = bit ? 0xff : 0x00;
- }
- }
- return glyph;
-}
-
-void qemu_pixman_glyph_render(pixman_image_t *glyph,
- pixman_image_t *surface,
- pixman_color_t *fgcol,
- pixman_color_t *bgcol,
- int x, int y, int cw, int ch)
-{
- pixman_image_t *ifg = pixman_image_create_solid_fill(fgcol);
- pixman_image_t *ibg = pixman_image_create_solid_fill(bgcol);
-
- pixman_image_composite(PIXMAN_OP_SRC, ibg, NULL, surface,
- 0, 0, 0, 0,
- cw * x, ch * y,
- cw, ch);
- pixman_image_composite(PIXMAN_OP_OVER, ifg, glyph, surface,
- 0, 0, 0, 0,
- cw * x, ch * y,
- cw, ch);
- pixman_image_unref(ifg);
- pixman_image_unref(ibg);
-}
diff --git a/qemu/ui/qemu-x509.h b/qemu/ui/qemu-x509.h
deleted file mode 100644
index 095aec161..000000000
--- a/qemu/ui/qemu-x509.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef QEMU_X509_H
-#define QEMU_X509_H
-
-#define X509_CA_CERT_FILE "ca-cert.pem"
-#define X509_CA_CRL_FILE "ca-crl.pem"
-#define X509_SERVER_KEY_FILE "server-key.pem"
-#define X509_SERVER_CERT_FILE "server-cert.pem"
-
-#endif /* QEMU_X509_H */
diff --git a/qemu/ui/sdl.c b/qemu/ui/sdl.c
deleted file mode 100644
index d8cf5bcf7..000000000
--- a/qemu/ui/sdl.c
+++ /dev/null
@@ -1,1027 +0,0 @@
-/*
- * QEMU SDL display driver
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* Avoid compiler warning because macro is redefined in SDL_syswm.h. */
-#undef WIN32_LEAN_AND_MEAN
-
-#include "qemu/osdep.h"
-#include <SDL.h>
-#include <SDL_syswm.h>
-
-#include "qemu-common.h"
-#include "qemu/cutils.h"
-#include "ui/console.h"
-#include "ui/input.h"
-#include "sysemu/sysemu.h"
-#include "x_keymap.h"
-#include "sdl_zoom.h"
-
-static DisplayChangeListener *dcl;
-static DisplaySurface *surface;
-static SDL_Surface *real_screen;
-static SDL_Surface *guest_screen = NULL;
-static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
-static int last_vm_running;
-static bool gui_saved_scaling;
-static int gui_saved_width;
-static int gui_saved_height;
-static int gui_saved_grab;
-static int gui_fullscreen;
-static int gui_noframe;
-static int gui_key_modifier_pressed;
-static int gui_keysym;
-static int gui_grab_code = KMOD_LALT | KMOD_LCTRL;
-static uint8_t modifiers_state[256];
-static SDL_Cursor *sdl_cursor_normal;
-static SDL_Cursor *sdl_cursor_hidden;
-static int absolute_enabled = 0;
-static int guest_cursor = 0;
-static int guest_x, guest_y;
-static SDL_Cursor *guest_sprite = NULL;
-static SDL_PixelFormat host_format;
-static int scaling_active = 0;
-static Notifier mouse_mode_notifier;
-static int idle_counter;
-
-#define SDL_REFRESH_INTERVAL_BUSY 10
-#define SDL_MAX_IDLE_COUNT (2 * GUI_REFRESH_INTERVAL_DEFAULT \
- / SDL_REFRESH_INTERVAL_BUSY + 1)
-
-#if 0
-#define DEBUG_SDL
-#endif
-
-static void sdl_update(DisplayChangeListener *dcl,
- int x, int y, int w, int h)
-{
- SDL_Rect rec;
- rec.x = x;
- rec.y = y;
- rec.w = w;
- rec.h = h;
-
-#ifdef DEBUG_SDL
- printf("SDL: Updating x=%d y=%d w=%d h=%d (scaling: %d)\n",
- x, y, w, h, scaling_active);
-#endif
-
- if (guest_screen) {
- if (!scaling_active) {
- SDL_BlitSurface(guest_screen, &rec, real_screen, &rec);
- } else {
- if (sdl_zoom_blit(guest_screen, real_screen, SMOOTHING_ON, &rec) < 0) {
- fprintf(stderr, "Zoom blit failed\n");
- exit(1);
- }
- }
- }
- SDL_UpdateRect(real_screen, rec.x, rec.y, rec.w, rec.h);
-}
-
-static void do_sdl_resize(int width, int height, int bpp)
-{
- int flags;
- SDL_Surface *tmp_screen;
-
-#ifdef DEBUG_SDL
- printf("SDL: Resizing to %dx%d bpp %d\n", width, height, bpp);
-#endif
-
- flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
- if (gui_fullscreen) {
- flags |= SDL_FULLSCREEN;
- } else {
- flags |= SDL_RESIZABLE;
- }
- if (gui_noframe)
- flags |= SDL_NOFRAME;
-
- tmp_screen = SDL_SetVideoMode(width, height, bpp, flags);
- if (!real_screen) {
- if (!tmp_screen) {
- fprintf(stderr, "Could not open SDL display (%dx%dx%d): %s\n",
- width, height, bpp, SDL_GetError());
- exit(1);
- }
- } else {
- /*
- * Revert to the previous video mode if the change of resizing or
- * resolution failed.
- */
- if (!tmp_screen) {
- fprintf(stderr, "Failed to set SDL display (%dx%dx%d): %s\n",
- width, height, bpp, SDL_GetError());
- return;
- }
- }
-
- real_screen = tmp_screen;
-}
-
-static void sdl_switch(DisplayChangeListener *dcl,
- DisplaySurface *new_surface)
-{
- PixelFormat pf;
-
- /* temporary hack: allows to call sdl_switch to handle scaling changes */
- if (new_surface) {
- surface = new_surface;
- }
- pf = qemu_pixelformat_from_pixman(surface->format);
-
- if (!scaling_active) {
- do_sdl_resize(surface_width(surface), surface_height(surface), 0);
- } else if (real_screen->format->BitsPerPixel !=
- surface_bits_per_pixel(surface)) {
- do_sdl_resize(real_screen->w, real_screen->h,
- surface_bits_per_pixel(surface));
- }
-
- if (guest_screen != NULL) {
- SDL_FreeSurface(guest_screen);
- }
-
-#ifdef DEBUG_SDL
- printf("SDL: Creating surface with masks: %08x %08x %08x %08x\n",
- pf.rmask, pf.gmask, pf.bmask, pf.amask);
-#endif
-
- guest_screen = SDL_CreateRGBSurfaceFrom
- (surface_data(surface),
- surface_width(surface), surface_height(surface),
- surface_bits_per_pixel(surface), surface_stride(surface),
- pf.rmask, pf.gmask,
- pf.bmask, pf.amask);
-}
-
-static bool sdl_check_format(DisplayChangeListener *dcl,
- pixman_format_code_t format)
-{
- /*
- * We let SDL convert for us a few more formats than,
- * the native ones. Thes are the ones I have tested.
- */
- return (format == PIXMAN_x8r8g8b8 ||
- format == PIXMAN_b8g8r8x8 ||
- format == PIXMAN_x1r5g5b5 ||
- format == PIXMAN_r5g6b5);
-}
-
-/* generic keyboard conversion */
-
-#include "sdl_keysym.h"
-
-static kbd_layout_t *kbd_layout = NULL;
-
-static uint8_t sdl_keyevent_to_keycode_generic(const SDL_KeyboardEvent *ev)
-{
- int keysym;
- /* workaround for X11+SDL bug with AltGR */
- keysym = ev->keysym.sym;
- if (keysym == 0 && ev->keysym.scancode == 113)
- keysym = SDLK_MODE;
- /* For Japanese key '\' and '|' */
- if (keysym == 92 && ev->keysym.scancode == 133) {
- keysym = 0xa5;
- }
- return keysym2scancode(kbd_layout, keysym) & SCANCODE_KEYMASK;
-}
-
-/* specific keyboard conversions from scan codes */
-
-#if defined(_WIN32)
-
-static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
-{
- return ev->keysym.scancode;
-}
-
-#else
-
-#if defined(SDL_VIDEO_DRIVER_X11)
-#include <X11/XKBlib.h>
-
-static int check_for_evdev(void)
-{
- SDL_SysWMinfo info;
- XkbDescPtr desc = NULL;
- int has_evdev = 0;
- char *keycodes = NULL;
-
- SDL_VERSION(&info.version);
- if (!SDL_GetWMInfo(&info)) {
- return 0;
- }
- desc = XkbGetKeyboard(info.info.x11.display,
- XkbGBN_AllComponentsMask,
- XkbUseCoreKbd);
- if (desc && desc->names) {
- keycodes = XGetAtomName(info.info.x11.display, desc->names->keycodes);
- if (keycodes == NULL) {
- fprintf(stderr, "could not lookup keycode name\n");
- } else if (strstart(keycodes, "evdev", NULL)) {
- has_evdev = 1;
- } else if (!strstart(keycodes, "xfree86", NULL)) {
- fprintf(stderr, "unknown keycodes `%s', please report to "
- "qemu-devel@nongnu.org\n", keycodes);
- }
- }
-
- if (desc) {
- XkbFreeKeyboard(desc, XkbGBN_AllComponentsMask, True);
- }
- if (keycodes) {
- XFree(keycodes);
- }
- return has_evdev;
-}
-#else
-static int check_for_evdev(void)
-{
- return 0;
-}
-#endif
-
-static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
-{
- int keycode;
- static int has_evdev = -1;
-
- if (has_evdev == -1)
- has_evdev = check_for_evdev();
-
- keycode = ev->keysym.scancode;
-
- if (keycode < 9) {
- keycode = 0;
- } else if (keycode < 97) {
- keycode -= 8; /* just an offset */
- } else if (keycode < 158) {
- /* use conversion table */
- if (has_evdev)
- keycode = translate_evdev_keycode(keycode - 97);
- else
- keycode = translate_xfree86_keycode(keycode - 97);
- } else if (keycode == 208) { /* Hiragana_Katakana */
- keycode = 0x70;
- } else if (keycode == 211) { /* backslash */
- keycode = 0x73;
- } else {
- keycode = 0;
- }
- return keycode;
-}
-
-#endif
-
-static void reset_keys(void)
-{
- int i;
- for(i = 0; i < 256; i++) {
- if (modifiers_state[i]) {
- qemu_input_event_send_key_number(dcl->con, i, false);
- modifiers_state[i] = 0;
- }
- }
-}
-
-static void sdl_process_key(SDL_KeyboardEvent *ev)
-{
- int keycode;
-
- if (ev->keysym.sym == SDLK_PAUSE) {
- /* specific case */
- qemu_input_event_send_key_qcode(dcl->con, Q_KEY_CODE_PAUSE,
- ev->type == SDL_KEYDOWN);
- return;
- }
-
- if (kbd_layout) {
- keycode = sdl_keyevent_to_keycode_generic(ev);
- } else {
- keycode = sdl_keyevent_to_keycode(ev);
- }
-
- switch(keycode) {
- case 0x00:
- /* sent when leaving window: reset the modifiers state */
- reset_keys();
- return;
- case 0x2a: /* Left Shift */
- case 0x36: /* Right Shift */
- case 0x1d: /* Left CTRL */
- case 0x9d: /* Right CTRL */
- case 0x38: /* Left ALT */
- case 0xb8: /* Right ALT */
- if (ev->type == SDL_KEYUP)
- modifiers_state[keycode] = 0;
- else
- modifiers_state[keycode] = 1;
- break;
-#define QEMU_SDL_VERSION ((SDL_MAJOR_VERSION << 8) + SDL_MINOR_VERSION)
-#if QEMU_SDL_VERSION < 0x102 || QEMU_SDL_VERSION == 0x102 && SDL_PATCHLEVEL < 14
- /* SDL versions before 1.2.14 don't support key up for caps/num lock. */
- case 0x45: /* num lock */
- case 0x3a: /* caps lock */
- /* SDL does not send the key up event, so we generate it */
- qemu_input_event_send_key_number(dcl->con, keycode, true);
- qemu_input_event_send_key_number(dcl->con, keycode, false);
- return;
-#endif
- }
-
- /* now send the key code */
- qemu_input_event_send_key_number(dcl->con, keycode,
- ev->type == SDL_KEYDOWN);
-}
-
-static void sdl_update_caption(void)
-{
- char win_title[1024];
- char icon_title[1024];
- const char *status = "";
-
- if (!runstate_is_running())
- status = " [Stopped]";
- else if (gui_grab) {
- if (alt_grab)
- status = " - Press Ctrl-Alt-Shift to exit mouse grab";
- else if (ctrl_grab)
- status = " - Press Right-Ctrl to exit mouse grab";
- else
- status = " - Press Ctrl-Alt to exit mouse grab";
- }
-
- if (qemu_name) {
- snprintf(win_title, sizeof(win_title), "QEMU (%s)%s", qemu_name, status);
- snprintf(icon_title, sizeof(icon_title), "QEMU (%s)", qemu_name);
- } else {
- snprintf(win_title, sizeof(win_title), "QEMU%s", status);
- snprintf(icon_title, sizeof(icon_title), "QEMU");
- }
-
- SDL_WM_SetCaption(win_title, icon_title);
-}
-
-static void sdl_hide_cursor(void)
-{
- if (!cursor_hide)
- return;
-
- if (qemu_input_is_absolute()) {
- SDL_ShowCursor(1);
- SDL_SetCursor(sdl_cursor_hidden);
- } else {
- SDL_ShowCursor(0);
- }
-}
-
-static void sdl_show_cursor(void)
-{
- if (!cursor_hide)
- return;
-
- if (!qemu_input_is_absolute() || !qemu_console_is_graphic(NULL)) {
- SDL_ShowCursor(1);
- if (guest_cursor &&
- (gui_grab || qemu_input_is_absolute() || absolute_enabled))
- SDL_SetCursor(guest_sprite);
- else
- SDL_SetCursor(sdl_cursor_normal);
- }
-}
-
-static void sdl_grab_start(void)
-{
- /*
- * If the application is not active, do not try to enter grab state. This
- * prevents 'SDL_WM_GrabInput(SDL_GRAB_ON)' from blocking all the
- * application (SDL bug).
- */
- if (!(SDL_GetAppState() & SDL_APPINPUTFOCUS)) {
- return;
- }
- if (guest_cursor) {
- SDL_SetCursor(guest_sprite);
- if (!qemu_input_is_absolute() && !absolute_enabled) {
- SDL_WarpMouse(guest_x, guest_y);
- }
- } else
- sdl_hide_cursor();
- SDL_WM_GrabInput(SDL_GRAB_ON);
- gui_grab = 1;
- sdl_update_caption();
-}
-
-static void sdl_grab_end(void)
-{
- SDL_WM_GrabInput(SDL_GRAB_OFF);
- gui_grab = 0;
- sdl_show_cursor();
- sdl_update_caption();
-}
-
-static void absolute_mouse_grab(void)
-{
- int mouse_x, mouse_y;
-
- SDL_GetMouseState(&mouse_x, &mouse_y);
- if (mouse_x > 0 && mouse_x < real_screen->w - 1 &&
- mouse_y > 0 && mouse_y < real_screen->h - 1) {
- sdl_grab_start();
- }
-}
-
-static void sdl_mouse_mode_change(Notifier *notify, void *data)
-{
- if (qemu_input_is_absolute()) {
- if (!absolute_enabled) {
- absolute_enabled = 1;
- if (qemu_console_is_graphic(NULL)) {
- absolute_mouse_grab();
- }
- }
- } else if (absolute_enabled) {
- if (!gui_fullscreen) {
- sdl_grab_end();
- }
- absolute_enabled = 0;
- }
-}
-
-static void sdl_send_mouse_event(int dx, int dy, int x, int y, int state)
-{
- static uint32_t bmap[INPUT_BUTTON__MAX] = {
- [INPUT_BUTTON_LEFT] = SDL_BUTTON(SDL_BUTTON_LEFT),
- [INPUT_BUTTON_MIDDLE] = SDL_BUTTON(SDL_BUTTON_MIDDLE),
- [INPUT_BUTTON_RIGHT] = SDL_BUTTON(SDL_BUTTON_RIGHT),
- [INPUT_BUTTON_WHEEL_UP] = SDL_BUTTON(SDL_BUTTON_WHEELUP),
- [INPUT_BUTTON_WHEEL_DOWN] = SDL_BUTTON(SDL_BUTTON_WHEELDOWN),
- };
- static uint32_t prev_state;
-
- if (prev_state != state) {
- qemu_input_update_buttons(dcl->con, bmap, prev_state, state);
- prev_state = state;
- }
-
- if (qemu_input_is_absolute()) {
- qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, x,
- real_screen->w);
- qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, y,
- real_screen->h);
- } else {
- if (guest_cursor) {
- x -= guest_x;
- y -= guest_y;
- guest_x += x;
- guest_y += y;
- dx = x;
- dy = y;
- }
- qemu_input_queue_rel(dcl->con, INPUT_AXIS_X, dx);
- qemu_input_queue_rel(dcl->con, INPUT_AXIS_Y, dy);
- }
- qemu_input_event_sync();
-}
-
-static void sdl_scale(int width, int height)
-{
- int bpp = real_screen->format->BitsPerPixel;
-
-#ifdef DEBUG_SDL
- printf("SDL: Scaling to %dx%d bpp %d\n", width, height, bpp);
-#endif
-
- if (bpp != 16 && bpp != 32) {
- bpp = 32;
- }
- do_sdl_resize(width, height, bpp);
- scaling_active = 1;
-}
-
-static void toggle_full_screen(void)
-{
- int width = surface_width(surface);
- int height = surface_height(surface);
- int bpp = surface_bits_per_pixel(surface);
-
- gui_fullscreen = !gui_fullscreen;
- if (gui_fullscreen) {
- gui_saved_width = real_screen->w;
- gui_saved_height = real_screen->h;
- gui_saved_scaling = scaling_active;
-
- do_sdl_resize(width, height, bpp);
- scaling_active = 0;
-
- gui_saved_grab = gui_grab;
- sdl_grab_start();
- } else {
- if (gui_saved_scaling) {
- sdl_scale(gui_saved_width, gui_saved_height);
- } else {
- do_sdl_resize(width, height, 0);
- }
- if (!gui_saved_grab || !qemu_console_is_graphic(NULL)) {
- sdl_grab_end();
- }
- }
- graphic_hw_invalidate(NULL);
- graphic_hw_update(NULL);
-}
-
-static void handle_keydown(SDL_Event *ev)
-{
- int mod_state;
- int keycode;
-
- if (alt_grab) {
- mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) ==
- (gui_grab_code | KMOD_LSHIFT);
- } else if (ctrl_grab) {
- mod_state = (SDL_GetModState() & KMOD_RCTRL) == KMOD_RCTRL;
- } else {
- mod_state = (SDL_GetModState() & gui_grab_code) == gui_grab_code;
- }
- gui_key_modifier_pressed = mod_state;
-
- if (gui_key_modifier_pressed) {
- keycode = sdl_keyevent_to_keycode(&ev->key);
- switch (keycode) {
- case 0x21: /* 'f' key on US keyboard */
- toggle_full_screen();
- gui_keysym = 1;
- break;
- case 0x16: /* 'u' key on US keyboard */
- if (scaling_active) {
- scaling_active = 0;
- sdl_switch(dcl, NULL);
- graphic_hw_invalidate(NULL);
- graphic_hw_update(NULL);
- }
- gui_keysym = 1;
- break;
- case 0x02 ... 0x0a: /* '1' to '9' keys */
- /* Reset the modifiers sent to the current console */
- reset_keys();
- console_select(keycode - 0x02);
- gui_keysym = 1;
- if (gui_fullscreen) {
- break;
- }
- if (!qemu_console_is_graphic(NULL)) {
- /* release grab if going to a text console */
- if (gui_grab) {
- sdl_grab_end();
- } else if (absolute_enabled) {
- sdl_show_cursor();
- }
- } else if (absolute_enabled) {
- sdl_hide_cursor();
- absolute_mouse_grab();
- }
- break;
- case 0x1b: /* '+' */
- case 0x35: /* '-' */
- if (!gui_fullscreen) {
- int width = MAX(real_screen->w + (keycode == 0x1b ? 50 : -50),
- 160);
- int height = (surface_height(surface) * width) /
- surface_width(surface);
-
- sdl_scale(width, height);
- graphic_hw_invalidate(NULL);
- graphic_hw_update(NULL);
- gui_keysym = 1;
- }
- default:
- break;
- }
- } else if (!qemu_console_is_graphic(NULL)) {
- int keysym = 0;
-
- if (ev->key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) {
- switch (ev->key.keysym.sym) {
- case SDLK_UP:
- keysym = QEMU_KEY_CTRL_UP;
- break;
- case SDLK_DOWN:
- keysym = QEMU_KEY_CTRL_DOWN;
- break;
- case SDLK_LEFT:
- keysym = QEMU_KEY_CTRL_LEFT;
- break;
- case SDLK_RIGHT:
- keysym = QEMU_KEY_CTRL_RIGHT;
- break;
- case SDLK_HOME:
- keysym = QEMU_KEY_CTRL_HOME;
- break;
- case SDLK_END:
- keysym = QEMU_KEY_CTRL_END;
- break;
- case SDLK_PAGEUP:
- keysym = QEMU_KEY_CTRL_PAGEUP;
- break;
- case SDLK_PAGEDOWN:
- keysym = QEMU_KEY_CTRL_PAGEDOWN;
- break;
- default:
- break;
- }
- } else {
- switch (ev->key.keysym.sym) {
- case SDLK_UP:
- keysym = QEMU_KEY_UP;
- break;
- case SDLK_DOWN:
- keysym = QEMU_KEY_DOWN;
- break;
- case SDLK_LEFT:
- keysym = QEMU_KEY_LEFT;
- break;
- case SDLK_RIGHT:
- keysym = QEMU_KEY_RIGHT;
- break;
- case SDLK_HOME:
- keysym = QEMU_KEY_HOME;
- break;
- case SDLK_END:
- keysym = QEMU_KEY_END;
- break;
- case SDLK_PAGEUP:
- keysym = QEMU_KEY_PAGEUP;
- break;
- case SDLK_PAGEDOWN:
- keysym = QEMU_KEY_PAGEDOWN;
- break;
- case SDLK_BACKSPACE:
- keysym = QEMU_KEY_BACKSPACE;
- break;
- case SDLK_DELETE:
- keysym = QEMU_KEY_DELETE;
- break;
- default:
- break;
- }
- }
- if (keysym) {
- kbd_put_keysym(keysym);
- } else if (ev->key.keysym.unicode != 0) {
- kbd_put_keysym(ev->key.keysym.unicode);
- }
- }
- if (qemu_console_is_graphic(NULL) && !gui_keysym) {
- sdl_process_key(&ev->key);
- }
-}
-
-static void handle_keyup(SDL_Event *ev)
-{
- int mod_state;
-
- if (!alt_grab) {
- mod_state = (ev->key.keysym.mod & gui_grab_code);
- } else {
- mod_state = (ev->key.keysym.mod & (gui_grab_code | KMOD_LSHIFT));
- }
- if (!mod_state && gui_key_modifier_pressed) {
- gui_key_modifier_pressed = 0;
- if (gui_keysym == 0) {
- /* exit/enter grab if pressing Ctrl-Alt */
- if (!gui_grab) {
- if (qemu_console_is_graphic(NULL)) {
- sdl_grab_start();
- }
- } else if (!gui_fullscreen) {
- sdl_grab_end();
- }
- /* SDL does not send back all the modifiers key, so we must
- * correct it. */
- reset_keys();
- return;
- }
- gui_keysym = 0;
- }
- if (qemu_console_is_graphic(NULL) && !gui_keysym) {
- sdl_process_key(&ev->key);
- }
-}
-
-static void handle_mousemotion(SDL_Event *ev)
-{
- int max_x, max_y;
-
- if (qemu_console_is_graphic(NULL) &&
- (qemu_input_is_absolute() || absolute_enabled)) {
- max_x = real_screen->w - 1;
- max_y = real_screen->h - 1;
- if (gui_grab && (ev->motion.x == 0 || ev->motion.y == 0 ||
- ev->motion.x == max_x || ev->motion.y == max_y)) {
- sdl_grab_end();
- }
- if (!gui_grab &&
- (ev->motion.x > 0 && ev->motion.x < max_x &&
- ev->motion.y > 0 && ev->motion.y < max_y)) {
- sdl_grab_start();
- }
- }
- if (gui_grab || qemu_input_is_absolute() || absolute_enabled) {
- sdl_send_mouse_event(ev->motion.xrel, ev->motion.yrel,
- ev->motion.x, ev->motion.y, ev->motion.state);
- }
-}
-
-static void handle_mousebutton(SDL_Event *ev)
-{
- int buttonstate = SDL_GetMouseState(NULL, NULL);
- SDL_MouseButtonEvent *bev;
-
- if (!qemu_console_is_graphic(NULL)) {
- return;
- }
-
- bev = &ev->button;
- if (!gui_grab && !qemu_input_is_absolute()) {
- if (ev->type == SDL_MOUSEBUTTONUP && bev->button == SDL_BUTTON_LEFT) {
- /* start grabbing all events */
- sdl_grab_start();
- }
- } else {
- if (ev->type == SDL_MOUSEBUTTONDOWN) {
- buttonstate |= SDL_BUTTON(bev->button);
- } else {
- buttonstate &= ~SDL_BUTTON(bev->button);
- }
- sdl_send_mouse_event(0, 0, bev->x, bev->y, buttonstate);
- }
-}
-
-static void handle_activation(SDL_Event *ev)
-{
-#ifdef _WIN32
- /* Disable grab if the window no longer has the focus
- * (Windows-only workaround) */
- if (gui_grab && ev->active.state == SDL_APPINPUTFOCUS &&
- !ev->active.gain && !gui_fullscreen) {
- sdl_grab_end();
- }
-#endif
- if (!gui_grab && ev->active.gain && qemu_console_is_graphic(NULL) &&
- (qemu_input_is_absolute() || absolute_enabled)) {
- absolute_mouse_grab();
- }
- if (ev->active.state & SDL_APPACTIVE) {
- if (ev->active.gain) {
- /* Back to default interval */
- update_displaychangelistener(dcl, GUI_REFRESH_INTERVAL_DEFAULT);
- } else {
- /* Sleeping interval. Not using the long default here as
- * sdl_refresh does not only update the guest screen, but
- * also checks for gui events. */
- update_displaychangelistener(dcl, 500);
- }
- }
-}
-
-static void sdl_refresh(DisplayChangeListener *dcl)
-{
- SDL_Event ev1, *ev = &ev1;
- int idle = 1;
-
- if (last_vm_running != runstate_is_running()) {
- last_vm_running = runstate_is_running();
- sdl_update_caption();
- }
-
- graphic_hw_update(NULL);
- SDL_EnableUNICODE(!qemu_console_is_graphic(NULL));
-
- while (SDL_PollEvent(ev)) {
- switch (ev->type) {
- case SDL_VIDEOEXPOSE:
- sdl_update(dcl, 0, 0, real_screen->w, real_screen->h);
- break;
- case SDL_KEYDOWN:
- idle = 0;
- handle_keydown(ev);
- break;
- case SDL_KEYUP:
- idle = 0;
- handle_keyup(ev);
- break;
- case SDL_QUIT:
- if (!no_quit) {
- no_shutdown = 0;
- qemu_system_shutdown_request();
- }
- break;
- case SDL_MOUSEMOTION:
- idle = 0;
- handle_mousemotion(ev);
- break;
- case SDL_MOUSEBUTTONDOWN:
- case SDL_MOUSEBUTTONUP:
- idle = 0;
- handle_mousebutton(ev);
- break;
- case SDL_ACTIVEEVENT:
- handle_activation(ev);
- break;
- case SDL_VIDEORESIZE:
- sdl_scale(ev->resize.w, ev->resize.h);
- graphic_hw_invalidate(NULL);
- graphic_hw_update(NULL);
- break;
- default:
- break;
- }
- }
-
- if (idle) {
- if (idle_counter < SDL_MAX_IDLE_COUNT) {
- idle_counter++;
- if (idle_counter >= SDL_MAX_IDLE_COUNT) {
- dcl->update_interval = GUI_REFRESH_INTERVAL_DEFAULT;
- }
- }
- } else {
- idle_counter = 0;
- dcl->update_interval = SDL_REFRESH_INTERVAL_BUSY;
- }
-}
-
-static void sdl_mouse_warp(DisplayChangeListener *dcl,
- int x, int y, int on)
-{
- if (on) {
- if (!guest_cursor)
- sdl_show_cursor();
- if (gui_grab || qemu_input_is_absolute() || absolute_enabled) {
- SDL_SetCursor(guest_sprite);
- if (!qemu_input_is_absolute() && !absolute_enabled) {
- SDL_WarpMouse(x, y);
- }
- }
- } else if (gui_grab)
- sdl_hide_cursor();
- guest_cursor = on;
- guest_x = x, guest_y = y;
-}
-
-static void sdl_mouse_define(DisplayChangeListener *dcl,
- QEMUCursor *c)
-{
- uint8_t *image, *mask;
- int bpl;
-
- if (guest_sprite)
- SDL_FreeCursor(guest_sprite);
-
- bpl = cursor_get_mono_bpl(c);
- image = g_malloc0(bpl * c->height);
- mask = g_malloc0(bpl * c->height);
- cursor_get_mono_image(c, 0x000000, image);
- cursor_get_mono_mask(c, 0, mask);
- guest_sprite = SDL_CreateCursor(image, mask, c->width, c->height,
- c->hot_x, c->hot_y);
- g_free(image);
- g_free(mask);
-
- if (guest_cursor &&
- (gui_grab || qemu_input_is_absolute() || absolute_enabled))
- SDL_SetCursor(guest_sprite);
-}
-
-static void sdl_cleanup(void)
-{
- if (guest_sprite)
- SDL_FreeCursor(guest_sprite);
- SDL_QuitSubSystem(SDL_INIT_VIDEO);
-}
-
-static const DisplayChangeListenerOps dcl_ops = {
- .dpy_name = "sdl",
- .dpy_gfx_update = sdl_update,
- .dpy_gfx_switch = sdl_switch,
- .dpy_gfx_check_format = sdl_check_format,
- .dpy_refresh = sdl_refresh,
- .dpy_mouse_set = sdl_mouse_warp,
- .dpy_cursor_define = sdl_mouse_define,
-};
-
-void sdl_display_early_init(int opengl)
-{
- if (opengl == 1 /* on */) {
- fprintf(stderr,
- "SDL1 display code has no opengl support.\n"
- "Please recompile qemu with SDL2, using\n"
- "./configure --enable-sdl --with-sdlabi=2.0\n");
- }
-}
-
-void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
-{
- int flags;
- uint8_t data = 0;
- const SDL_VideoInfo *vi;
- char *filename;
-
-#if defined(__APPLE__)
- /* always use generic keymaps */
- if (!keyboard_layout)
- keyboard_layout = "en-us";
-#endif
- if(keyboard_layout) {
- kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
- if (!kbd_layout)
- exit(1);
- }
-
- if (no_frame)
- gui_noframe = 1;
-
- if (!full_screen) {
- setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 0);
- }
-#ifdef __linux__
- /* on Linux, SDL may use fbcon|directfb|svgalib when run without
- * accessible $DISPLAY to open X11 window. This is often the case
- * when qemu is run using sudo. But in this case, and when actually
- * run in X11 environment, SDL fights with X11 for the video card,
- * making current display unavailable, often until reboot.
- * So make x11 the default SDL video driver if this variable is unset.
- * This is a bit hackish but saves us from bigger problem.
- * Maybe it's a good idea to fix this in SDL instead.
- */
- setenv("SDL_VIDEODRIVER", "x11", 0);
-#endif
-
- /* Enable normal up/down events for Caps-Lock and Num-Lock keys.
- * This requires SDL >= 1.2.14. */
- setenv("SDL_DISABLE_LOCK_KEYS", "1", 1);
-
- flags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE;
- if (SDL_Init (flags)) {
- fprintf(stderr, "Could not initialize SDL(%s) - exiting\n",
- SDL_GetError());
- exit(1);
- }
- vi = SDL_GetVideoInfo();
- host_format = *(vi->vfmt);
-
- /* Load a 32x32x4 image. White pixels are transparent. */
- filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "qemu-icon.bmp");
- if (filename) {
- SDL_Surface *image = SDL_LoadBMP(filename);
- if (image) {
- uint32_t colorkey = SDL_MapRGB(image->format, 255, 255, 255);
- SDL_SetColorKey(image, SDL_SRCCOLORKEY, colorkey);
- SDL_WM_SetIcon(image, NULL);
- }
- g_free(filename);
- }
-
- if (full_screen) {
- gui_fullscreen = 1;
- sdl_grab_start();
- }
-
- dcl = g_new0(DisplayChangeListener, 1);
- dcl->ops = &dcl_ops;
- register_displaychangelistener(dcl);
-
- mouse_mode_notifier.notify = sdl_mouse_mode_change;
- qemu_add_mouse_mode_change_notifier(&mouse_mode_notifier);
-
- sdl_update_caption();
- SDL_EnableKeyRepeat(250, 50);
- gui_grab = 0;
-
- sdl_cursor_hidden = SDL_CreateCursor(&data, &data, 8, 1, 0, 0);
- sdl_cursor_normal = SDL_GetCursor();
-
- atexit(sdl_cleanup);
-}
diff --git a/qemu/ui/sdl2-2d.c b/qemu/ui/sdl2-2d.c
deleted file mode 100644
index 95930061e..000000000
--- a/qemu/ui/sdl2-2d.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * QEMU SDL display driver
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-/* Ported SDL 1.2 code to 2.0 by Dave Airlie. */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "ui/console.h"
-#include "ui/input.h"
-#include "ui/sdl2.h"
-#include "sysemu/sysemu.h"
-
-void sdl2_2d_update(DisplayChangeListener *dcl,
- int x, int y, int w, int h)
-{
- struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
- DisplaySurface *surf = qemu_console_surface(dcl->con);
- SDL_Rect rect;
-
- assert(!scon->opengl);
-
- if (!surf) {
- return;
- }
- if (!scon->texture) {
- return;
- }
-
- /*
- * SDL2 seems to do some double-buffering, and trying to only
- * update the changed areas results in only one of the two buffers
- * being updated. Which flickers alot. So lets not try to be
- * clever do a full update every time ...
- */
-#if 0
- rect.x = x;
- rect.y = y;
- rect.w = w;
- rect.h = h;
-#else
- rect.x = 0;
- rect.y = 0;
- rect.w = surface_width(surf);
- rect.h = surface_height(surf);
-#endif
-
- SDL_UpdateTexture(scon->texture, NULL, surface_data(surf),
- surface_stride(surf));
- SDL_RenderCopy(scon->real_renderer, scon->texture, &rect, &rect);
- SDL_RenderPresent(scon->real_renderer);
-}
-
-void sdl2_2d_switch(DisplayChangeListener *dcl,
- DisplaySurface *new_surface)
-{
- struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
- DisplaySurface *old_surface = scon->surface;
- int format = 0;
-
- assert(!scon->opengl);
-
- scon->surface = new_surface;
-
- if (scon->texture) {
- SDL_DestroyTexture(scon->texture);
- scon->texture = NULL;
- }
-
- if (!new_surface) {
- sdl2_window_destroy(scon);
- return;
- }
-
- if (!scon->real_window) {
- sdl2_window_create(scon);
- } else if (old_surface &&
- ((surface_width(old_surface) != surface_width(new_surface)) ||
- (surface_height(old_surface) != surface_height(new_surface)))) {
- sdl2_window_resize(scon);
- }
-
- SDL_RenderSetLogicalSize(scon->real_renderer,
- surface_width(new_surface),
- surface_height(new_surface));
-
- switch (surface_format(scon->surface)) {
- case PIXMAN_x1r5g5b5:
- format = SDL_PIXELFORMAT_ARGB1555;
- break;
- case PIXMAN_r5g6b5:
- format = SDL_PIXELFORMAT_RGB565;
- break;
- case PIXMAN_x8r8g8b8:
- format = SDL_PIXELFORMAT_ARGB8888;
- break;
- case PIXMAN_r8g8b8x8:
- format = SDL_PIXELFORMAT_RGBA8888;
- break;
- default:
- g_assert_not_reached();
- }
- scon->texture = SDL_CreateTexture(scon->real_renderer, format,
- SDL_TEXTUREACCESS_STREAMING,
- surface_width(new_surface),
- surface_height(new_surface));
- sdl2_2d_redraw(scon);
-}
-
-void sdl2_2d_refresh(DisplayChangeListener *dcl)
-{
- struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
-
- assert(!scon->opengl);
- graphic_hw_update(dcl->con);
- sdl2_poll_events(scon);
-}
-
-void sdl2_2d_redraw(struct sdl2_console *scon)
-{
- assert(!scon->opengl);
-
- if (!scon->surface) {
- return;
- }
- sdl2_2d_update(&scon->dcl, 0, 0,
- surface_width(scon->surface),
- surface_height(scon->surface));
-}
-
-bool sdl2_2d_check_format(DisplayChangeListener *dcl,
- pixman_format_code_t format)
-{
- /*
- * We let SDL convert for us a few more formats than,
- * the native ones. Thes are the ones I have tested.
- */
- return (format == PIXMAN_x8r8g8b8 ||
- format == PIXMAN_b8g8r8x8 ||
- format == PIXMAN_x1r5g5b5 ||
- format == PIXMAN_r5g6b5);
-}
diff --git a/qemu/ui/sdl2-gl.c b/qemu/ui/sdl2-gl.c
deleted file mode 100644
index a324ecaca..000000000
--- a/qemu/ui/sdl2-gl.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * QEMU SDL display driver -- opengl support
- *
- * Copyright (c) 2014 Red Hat
- *
- * Authors:
- * Gerd Hoffmann <kraxel@redhat.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "ui/console.h"
-#include "ui/input.h"
-#include "ui/sdl2.h"
-#include "sysemu/sysemu.h"
-
-#include <epoxy/gl.h>
-
-static void sdl2_set_scanout_mode(struct sdl2_console *scon, bool scanout)
-{
- if (scon->scanout_mode == scanout) {
- return;
- }
-
- scon->scanout_mode = scanout;
- if (!scon->scanout_mode) {
- if (scon->fbo_id) {
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, 0, 0);
- glDeleteFramebuffers(1, &scon->fbo_id);
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
- scon->fbo_id = 0;
- }
- if (scon->surface) {
- surface_gl_destroy_texture(scon->gls, scon->surface);
- surface_gl_create_texture(scon->gls, scon->surface);
- }
- }
-}
-
-static void sdl2_gl_render_surface(struct sdl2_console *scon)
-{
- int ww, wh;
-
- SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
- sdl2_set_scanout_mode(scon, false);
-
- SDL_GetWindowSize(scon->real_window, &ww, &wh);
- surface_gl_setup_viewport(scon->gls, scon->surface, ww, wh);
-
- surface_gl_render_texture(scon->gls, scon->surface);
- SDL_GL_SwapWindow(scon->real_window);
-}
-
-void sdl2_gl_update(DisplayChangeListener *dcl,
- int x, int y, int w, int h)
-{
- struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
-
- assert(scon->opengl);
-
- SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
- surface_gl_update_texture(scon->gls, scon->surface, x, y, w, h);
- scon->updates++;
-}
-
-void sdl2_gl_switch(DisplayChangeListener *dcl,
- DisplaySurface *new_surface)
-{
- struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
- DisplaySurface *old_surface = scon->surface;
-
- assert(scon->opengl);
-
- SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
- surface_gl_destroy_texture(scon->gls, scon->surface);
-
- scon->surface = new_surface;
-
- if (!new_surface) {
- console_gl_fini_context(scon->gls);
- scon->gls = NULL;
- sdl2_window_destroy(scon);
- return;
- }
-
- if (!scon->real_window) {
- sdl2_window_create(scon);
- scon->gls = console_gl_init_context();
- } else if (old_surface &&
- ((surface_width(old_surface) != surface_width(new_surface)) ||
- (surface_height(old_surface) != surface_height(new_surface)))) {
- sdl2_window_resize(scon);
- }
-
- surface_gl_create_texture(scon->gls, scon->surface);
-}
-
-void sdl2_gl_refresh(DisplayChangeListener *dcl)
-{
- struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
-
- assert(scon->opengl);
-
- graphic_hw_update(dcl->con);
- if (scon->updates && scon->surface) {
- scon->updates = 0;
- sdl2_gl_render_surface(scon);
- }
- sdl2_poll_events(scon);
-}
-
-void sdl2_gl_redraw(struct sdl2_console *scon)
-{
- assert(scon->opengl);
-
- if (scon->surface) {
- sdl2_gl_render_surface(scon);
- }
-}
-
-QEMUGLContext sdl2_gl_create_context(DisplayChangeListener *dcl,
- QEMUGLParams *params)
-{
- struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
- SDL_GLContext ctx;
-
- assert(scon->opengl);
-
- SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
-
- SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
- SDL_GL_CONTEXT_PROFILE_CORE);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, params->major_ver);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, params->minor_ver);
-
- ctx = SDL_GL_CreateContext(scon->real_window);
- return (QEMUGLContext)ctx;
-}
-
-void sdl2_gl_destroy_context(DisplayChangeListener *dcl, QEMUGLContext ctx)
-{
- SDL_GLContext sdlctx = (SDL_GLContext)ctx;
-
- SDL_GL_DeleteContext(sdlctx);
-}
-
-int sdl2_gl_make_context_current(DisplayChangeListener *dcl,
- QEMUGLContext ctx)
-{
- struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
- SDL_GLContext sdlctx = (SDL_GLContext)ctx;
-
- assert(scon->opengl);
-
- return SDL_GL_MakeCurrent(scon->real_window, sdlctx);
-}
-
-QEMUGLContext sdl2_gl_get_current_context(DisplayChangeListener *dcl)
-{
- SDL_GLContext sdlctx;
-
- sdlctx = SDL_GL_GetCurrentContext();
- return (QEMUGLContext)sdlctx;
-}
-
-void sdl2_gl_scanout(DisplayChangeListener *dcl,
- uint32_t backing_id, bool backing_y_0_top,
- uint32_t x, uint32_t y,
- uint32_t w, uint32_t h)
-{
- struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
-
- assert(scon->opengl);
- scon->x = x;
- scon->y = y;
- scon->w = w;
- scon->h = h;
- scon->tex_id = backing_id;
- scon->y0_top = backing_y_0_top;
-
- SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
-
- if (scon->tex_id == 0 || scon->w == 0 || scon->h == 0) {
- sdl2_set_scanout_mode(scon, false);
- return;
- }
-
- sdl2_set_scanout_mode(scon, true);
- if (!scon->fbo_id) {
- glGenFramebuffers(1, &scon->fbo_id);
- }
-
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, scon->fbo_id);
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, scon->tex_id, 0);
-}
-
-void sdl2_gl_scanout_flush(DisplayChangeListener *dcl,
- uint32_t x, uint32_t y, uint32_t w, uint32_t h)
-{
- struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
- int ww, wh, y1, y2;
-
- assert(scon->opengl);
- if (!scon->scanout_mode) {
- return;
- }
- if (!scon->fbo_id) {
- return;
- }
-
- SDL_GL_MakeCurrent(scon->real_window, scon->winctx);
-
- glBindFramebuffer(GL_READ_FRAMEBUFFER, scon->fbo_id);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
-
- SDL_GetWindowSize(scon->real_window, &ww, &wh);
- glViewport(0, 0, ww, wh);
- y1 = scon->y0_top ? 0 : scon->h;
- y2 = scon->y0_top ? scon->h : 0;
- glBlitFramebuffer(0, y1, scon->w, y2,
- 0, 0, ww, wh,
- GL_COLOR_BUFFER_BIT, GL_NEAREST);
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, scon->fbo_id);
-
- SDL_GL_SwapWindow(scon->real_window);
-}
diff --git a/qemu/ui/sdl2-input.c b/qemu/ui/sdl2-input.c
deleted file mode 100644
index 6e315ae80..000000000
--- a/qemu/ui/sdl2-input.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * QEMU SDL display driver
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-/* Ported SDL 1.2 code to 2.0 by Dave Airlie. */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "ui/console.h"
-#include "ui/input.h"
-#include "ui/sdl2.h"
-#include "sysemu/sysemu.h"
-
-#include "sdl2-keymap.h"
-
-static uint8_t modifiers_state[SDL_NUM_SCANCODES];
-
-void sdl2_reset_keys(struct sdl2_console *scon)
-{
- QemuConsole *con = scon ? scon->dcl.con : NULL;
- int i;
-
- for (i = 0; i < SDL_NUM_SCANCODES; i++) {
- if (modifiers_state[i]) {
- int qcode = sdl2_scancode_to_qcode[i];
- qemu_input_event_send_key_qcode(con, qcode, false);
- modifiers_state[i] = 0;
- }
- }
-}
-
-void sdl2_process_key(struct sdl2_console *scon,
- SDL_KeyboardEvent *ev)
-{
- int qcode = sdl2_scancode_to_qcode[ev->keysym.scancode];
- QemuConsole *con = scon ? scon->dcl.con : NULL;
-
- if (!qemu_console_is_graphic(con)) {
- if (ev->type == SDL_KEYDOWN) {
- switch (ev->keysym.scancode) {
- case SDL_SCANCODE_RETURN:
- kbd_put_keysym_console(con, '\n');
- break;
- case SDL_SCANCODE_BACKSPACE:
- kbd_put_keysym_console(con, QEMU_KEY_BACKSPACE);
- break;
- default:
- kbd_put_qcode_console(con, qcode);
- break;
- }
- }
- return;
- }
-
- switch (ev->keysym.scancode) {
-#if 0
- case SDL_SCANCODE_NUMLOCKCLEAR:
- case SDL_SCANCODE_CAPSLOCK:
- /* SDL does not send the key up event, so we generate it */
- qemu_input_event_send_key_qcode(con, qcode, true);
- qemu_input_event_send_key_qcode(con, qcode, false);
- return;
-#endif
- case SDL_SCANCODE_LCTRL:
- case SDL_SCANCODE_LSHIFT:
- case SDL_SCANCODE_LALT:
- case SDL_SCANCODE_LGUI:
- case SDL_SCANCODE_RCTRL:
- case SDL_SCANCODE_RSHIFT:
- case SDL_SCANCODE_RALT:
- case SDL_SCANCODE_RGUI:
- if (ev->type == SDL_KEYUP) {
- modifiers_state[ev->keysym.scancode] = 0;
- } else {
- modifiers_state[ev->keysym.scancode] = 1;
- }
- /* fall though */
- default:
- qemu_input_event_send_key_qcode(con, qcode,
- ev->type == SDL_KEYDOWN);
- }
-}
diff --git a/qemu/ui/sdl2-keymap.h b/qemu/ui/sdl2-keymap.h
deleted file mode 100644
index cbedaa477..000000000
--- a/qemu/ui/sdl2-keymap.h
+++ /dev/null
@@ -1,267 +0,0 @@
-
-/* map SDL2 scancodes to QKeyCode */
-
-static const int sdl2_scancode_to_qcode[SDL_NUM_SCANCODES] = {
- [SDL_SCANCODE_A] = Q_KEY_CODE_A,
- [SDL_SCANCODE_B] = Q_KEY_CODE_B,
- [SDL_SCANCODE_C] = Q_KEY_CODE_C,
- [SDL_SCANCODE_D] = Q_KEY_CODE_D,
- [SDL_SCANCODE_E] = Q_KEY_CODE_E,
- [SDL_SCANCODE_F] = Q_KEY_CODE_F,
- [SDL_SCANCODE_G] = Q_KEY_CODE_G,
- [SDL_SCANCODE_H] = Q_KEY_CODE_H,
- [SDL_SCANCODE_I] = Q_KEY_CODE_I,
- [SDL_SCANCODE_J] = Q_KEY_CODE_J,
- [SDL_SCANCODE_K] = Q_KEY_CODE_K,
- [SDL_SCANCODE_L] = Q_KEY_CODE_L,
- [SDL_SCANCODE_M] = Q_KEY_CODE_M,
- [SDL_SCANCODE_N] = Q_KEY_CODE_N,
- [SDL_SCANCODE_O] = Q_KEY_CODE_O,
- [SDL_SCANCODE_P] = Q_KEY_CODE_P,
- [SDL_SCANCODE_Q] = Q_KEY_CODE_Q,
- [SDL_SCANCODE_R] = Q_KEY_CODE_R,
- [SDL_SCANCODE_S] = Q_KEY_CODE_S,
- [SDL_SCANCODE_T] = Q_KEY_CODE_T,
- [SDL_SCANCODE_U] = Q_KEY_CODE_U,
- [SDL_SCANCODE_V] = Q_KEY_CODE_V,
- [SDL_SCANCODE_W] = Q_KEY_CODE_W,
- [SDL_SCANCODE_X] = Q_KEY_CODE_X,
- [SDL_SCANCODE_Y] = Q_KEY_CODE_Y,
- [SDL_SCANCODE_Z] = Q_KEY_CODE_Z,
-
- [SDL_SCANCODE_1] = Q_KEY_CODE_1,
- [SDL_SCANCODE_2] = Q_KEY_CODE_2,
- [SDL_SCANCODE_3] = Q_KEY_CODE_3,
- [SDL_SCANCODE_4] = Q_KEY_CODE_4,
- [SDL_SCANCODE_5] = Q_KEY_CODE_5,
- [SDL_SCANCODE_6] = Q_KEY_CODE_6,
- [SDL_SCANCODE_7] = Q_KEY_CODE_7,
- [SDL_SCANCODE_8] = Q_KEY_CODE_8,
- [SDL_SCANCODE_9] = Q_KEY_CODE_9,
- [SDL_SCANCODE_0] = Q_KEY_CODE_0,
-
- [SDL_SCANCODE_RETURN] = Q_KEY_CODE_RET,
- [SDL_SCANCODE_ESCAPE] = Q_KEY_CODE_ESC,
- [SDL_SCANCODE_BACKSPACE] = Q_KEY_CODE_BACKSPACE,
- [SDL_SCANCODE_TAB] = Q_KEY_CODE_TAB,
- [SDL_SCANCODE_SPACE] = Q_KEY_CODE_SPC,
- [SDL_SCANCODE_MINUS] = Q_KEY_CODE_MINUS,
- [SDL_SCANCODE_EQUALS] = Q_KEY_CODE_EQUAL,
- [SDL_SCANCODE_LEFTBRACKET] = Q_KEY_CODE_BRACKET_LEFT,
- [SDL_SCANCODE_RIGHTBRACKET] = Q_KEY_CODE_BRACKET_RIGHT,
- [SDL_SCANCODE_BACKSLASH] = Q_KEY_CODE_BACKSLASH,
-#if 0
- [SDL_SCANCODE_NONUSHASH] = Q_KEY_CODE_NONUSHASH,
-#endif
- [SDL_SCANCODE_SEMICOLON] = Q_KEY_CODE_SEMICOLON,
- [SDL_SCANCODE_APOSTROPHE] = Q_KEY_CODE_APOSTROPHE,
- [SDL_SCANCODE_GRAVE] = Q_KEY_CODE_GRAVE_ACCENT,
- [SDL_SCANCODE_COMMA] = Q_KEY_CODE_COMMA,
- [SDL_SCANCODE_PERIOD] = Q_KEY_CODE_DOT,
- [SDL_SCANCODE_SLASH] = Q_KEY_CODE_SLASH,
- [SDL_SCANCODE_CAPSLOCK] = Q_KEY_CODE_CAPS_LOCK,
-
- [SDL_SCANCODE_F1] = Q_KEY_CODE_F1,
- [SDL_SCANCODE_F2] = Q_KEY_CODE_F2,
- [SDL_SCANCODE_F3] = Q_KEY_CODE_F3,
- [SDL_SCANCODE_F4] = Q_KEY_CODE_F4,
- [SDL_SCANCODE_F5] = Q_KEY_CODE_F5,
- [SDL_SCANCODE_F6] = Q_KEY_CODE_F6,
- [SDL_SCANCODE_F7] = Q_KEY_CODE_F7,
- [SDL_SCANCODE_F8] = Q_KEY_CODE_F8,
- [SDL_SCANCODE_F9] = Q_KEY_CODE_F9,
- [SDL_SCANCODE_F10] = Q_KEY_CODE_F10,
- [SDL_SCANCODE_F11] = Q_KEY_CODE_F11,
- [SDL_SCANCODE_F12] = Q_KEY_CODE_F12,
-
- [SDL_SCANCODE_PRINTSCREEN] = Q_KEY_CODE_PRINT,
- [SDL_SCANCODE_SCROLLLOCK] = Q_KEY_CODE_SCROLL_LOCK,
- [SDL_SCANCODE_PAUSE] = Q_KEY_CODE_PAUSE,
- [SDL_SCANCODE_INSERT] = Q_KEY_CODE_INSERT,
- [SDL_SCANCODE_HOME] = Q_KEY_CODE_HOME,
- [SDL_SCANCODE_PAGEUP] = Q_KEY_CODE_PGUP,
- [SDL_SCANCODE_DELETE] = Q_KEY_CODE_DELETE,
- [SDL_SCANCODE_END] = Q_KEY_CODE_END,
- [SDL_SCANCODE_PAGEDOWN] = Q_KEY_CODE_PGDN,
- [SDL_SCANCODE_RIGHT] = Q_KEY_CODE_RIGHT,
- [SDL_SCANCODE_LEFT] = Q_KEY_CODE_LEFT,
- [SDL_SCANCODE_DOWN] = Q_KEY_CODE_DOWN,
- [SDL_SCANCODE_UP] = Q_KEY_CODE_UP,
- [SDL_SCANCODE_NUMLOCKCLEAR] = Q_KEY_CODE_NUM_LOCK,
-
- [SDL_SCANCODE_KP_DIVIDE] = Q_KEY_CODE_KP_DIVIDE,
- [SDL_SCANCODE_KP_MULTIPLY] = Q_KEY_CODE_KP_MULTIPLY,
- [SDL_SCANCODE_KP_MINUS] = Q_KEY_CODE_KP_SUBTRACT,
- [SDL_SCANCODE_KP_PLUS] = Q_KEY_CODE_KP_ADD,
- [SDL_SCANCODE_KP_ENTER] = Q_KEY_CODE_KP_ENTER,
- [SDL_SCANCODE_KP_1] = Q_KEY_CODE_KP_1,
- [SDL_SCANCODE_KP_2] = Q_KEY_CODE_KP_2,
- [SDL_SCANCODE_KP_3] = Q_KEY_CODE_KP_3,
- [SDL_SCANCODE_KP_4] = Q_KEY_CODE_KP_4,
- [SDL_SCANCODE_KP_5] = Q_KEY_CODE_KP_5,
- [SDL_SCANCODE_KP_6] = Q_KEY_CODE_KP_6,
- [SDL_SCANCODE_KP_7] = Q_KEY_CODE_KP_7,
- [SDL_SCANCODE_KP_8] = Q_KEY_CODE_KP_8,
- [SDL_SCANCODE_KP_9] = Q_KEY_CODE_KP_9,
- [SDL_SCANCODE_KP_0] = Q_KEY_CODE_KP_0,
- [SDL_SCANCODE_KP_PERIOD] = Q_KEY_CODE_KP_DECIMAL,
-
- [SDL_SCANCODE_NONUSBACKSLASH] = Q_KEY_CODE_LESS,
- [SDL_SCANCODE_APPLICATION] = Q_KEY_CODE_MENU,
-#if 0
- [SDL_SCANCODE_POWER] = Q_KEY_CODE_POWER,
- [SDL_SCANCODE_KP_EQUALS] = Q_KEY_CODE_KP_EQUALS,
-
- [SDL_SCANCODE_F13] = Q_KEY_CODE_F13,
- [SDL_SCANCODE_F14] = Q_KEY_CODE_F14,
- [SDL_SCANCODE_F15] = Q_KEY_CODE_F15,
- [SDL_SCANCODE_F16] = Q_KEY_CODE_F16,
- [SDL_SCANCODE_F17] = Q_KEY_CODE_F17,
- [SDL_SCANCODE_F18] = Q_KEY_CODE_F18,
- [SDL_SCANCODE_F19] = Q_KEY_CODE_F19,
- [SDL_SCANCODE_F20] = Q_KEY_CODE_F20,
- [SDL_SCANCODE_F21] = Q_KEY_CODE_F21,
- [SDL_SCANCODE_F22] = Q_KEY_CODE_F22,
- [SDL_SCANCODE_F23] = Q_KEY_CODE_F23,
- [SDL_SCANCODE_F24] = Q_KEY_CODE_F24,
-
- [SDL_SCANCODE_EXECUTE] = Q_KEY_CODE_EXECUTE,
-#endif
- [SDL_SCANCODE_HELP] = Q_KEY_CODE_HELP,
- [SDL_SCANCODE_MENU] = Q_KEY_CODE_MENU,
-#if 0
- [SDL_SCANCODE_SELECT] = Q_KEY_CODE_SELECT,
-#endif
- [SDL_SCANCODE_STOP] = Q_KEY_CODE_STOP,
- [SDL_SCANCODE_AGAIN] = Q_KEY_CODE_AGAIN,
- [SDL_SCANCODE_UNDO] = Q_KEY_CODE_UNDO,
- [SDL_SCANCODE_CUT] = Q_KEY_CODE_CUT,
- [SDL_SCANCODE_COPY] = Q_KEY_CODE_COPY,
- [SDL_SCANCODE_PASTE] = Q_KEY_CODE_PASTE,
- [SDL_SCANCODE_FIND] = Q_KEY_CODE_FIND,
-#if 0
- [SDL_SCANCODE_MUTE] = Q_KEY_CODE_MUTE,
- [SDL_SCANCODE_VOLUMEUP] = Q_KEY_CODE_VOLUMEUP,
- [SDL_SCANCODE_VOLUMEDOWN] = Q_KEY_CODE_VOLUMEDOWN,
-
- [SDL_SCANCODE_KP_COMMA] = Q_KEY_CODE_KP_COMMA,
- [SDL_SCANCODE_KP_EQUALSAS400] = Q_KEY_CODE_KP_EQUALSAS400,
-
- [SDL_SCANCODE_INTERNATIONAL1] = Q_KEY_CODE_INTERNATIONAL1,
- [SDL_SCANCODE_INTERNATIONAL2] = Q_KEY_CODE_INTERNATIONAL2,
- [SDL_SCANCODE_INTERNATIONAL3] = Q_KEY_CODE_INTERNATIONAL3,
- [SDL_SCANCODE_INTERNATIONAL4] = Q_KEY_CODE_INTERNATIONAL4,
- [SDL_SCANCODE_INTERNATIONAL5] = Q_KEY_CODE_INTERNATIONAL5,
- [SDL_SCANCODE_INTERNATIONAL6] = Q_KEY_CODE_INTERNATIONAL6,
- [SDL_SCANCODE_INTERNATIONAL7] = Q_KEY_CODE_INTERNATIONAL7,
- [SDL_SCANCODE_INTERNATIONAL8] = Q_KEY_CODE_INTERNATIONAL8,
- [SDL_SCANCODE_INTERNATIONAL9] = Q_KEY_CODE_INTERNATIONAL9,
- [SDL_SCANCODE_LANG1] = Q_KEY_CODE_LANG1,
- [SDL_SCANCODE_LANG2] = Q_KEY_CODE_LANG2,
- [SDL_SCANCODE_LANG3] = Q_KEY_CODE_LANG3,
- [SDL_SCANCODE_LANG4] = Q_KEY_CODE_LANG4,
- [SDL_SCANCODE_LANG5] = Q_KEY_CODE_LANG5,
- [SDL_SCANCODE_LANG6] = Q_KEY_CODE_LANG6,
- [SDL_SCANCODE_LANG7] = Q_KEY_CODE_LANG7,
- [SDL_SCANCODE_LANG8] = Q_KEY_CODE_LANG8,
- [SDL_SCANCODE_LANG9] = Q_KEY_CODE_LANG9,
- [SDL_SCANCODE_ALTERASE] = Q_KEY_CODE_ALTERASE,
-#endif
- [SDL_SCANCODE_SYSREQ] = Q_KEY_CODE_SYSRQ,
-#if 0
- [SDL_SCANCODE_CANCEL] = Q_KEY_CODE_CANCEL,
- [SDL_SCANCODE_CLEAR] = Q_KEY_CODE_CLEAR,
- [SDL_SCANCODE_PRIOR] = Q_KEY_CODE_PRIOR,
- [SDL_SCANCODE_RETURN2] = Q_KEY_CODE_RETURN2,
- [SDL_SCANCODE_SEPARATOR] = Q_KEY_CODE_SEPARATOR,
- [SDL_SCANCODE_OUT] = Q_KEY_CODE_OUT,
- [SDL_SCANCODE_OPER] = Q_KEY_CODE_OPER,
- [SDL_SCANCODE_CLEARAGAIN] = Q_KEY_CODE_CLEARAGAIN,
- [SDL_SCANCODE_CRSEL] = Q_KEY_CODE_CRSEL,
- [SDL_SCANCODE_EXSEL] = Q_KEY_CODE_EXSEL,
- [SDL_SCANCODE_KP_00] = Q_KEY_CODE_KP_00,
- [SDL_SCANCODE_KP_000] = Q_KEY_CODE_KP_000,
- [SDL_SCANCODE_THOUSANDSSEPARATOR] = Q_KEY_CODE_THOUSANDSSEPARATOR,
- [SDL_SCANCODE_DECIMALSEPARATOR] = Q_KEY_CODE_DECIMALSEPARATOR,
- [SDL_SCANCODE_CURRENCYUNIT] = Q_KEY_CODE_CURRENCYUNIT,
- [SDL_SCANCODE_CURRENCYSUBUNIT] = Q_KEY_CODE_CURRENCYSUBUNIT,
- [SDL_SCANCODE_KP_LEFTPAREN] = Q_KEY_CODE_KP_LEFTPAREN,
- [SDL_SCANCODE_KP_RIGHTPAREN] = Q_KEY_CODE_KP_RIGHTPAREN,
- [SDL_SCANCODE_KP_LEFTBRACE] = Q_KEY_CODE_KP_LEFTBRACE,
- [SDL_SCANCODE_KP_RIGHTBRACE] = Q_KEY_CODE_KP_RIGHTBRACE,
- [SDL_SCANCODE_KP_TAB] = Q_KEY_CODE_KP_TAB,
- [SDL_SCANCODE_KP_BACKSPACE] = Q_KEY_CODE_KP_BACKSPACE,
- [SDL_SCANCODE_KP_A] = Q_KEY_CODE_KP_A,
- [SDL_SCANCODE_KP_B] = Q_KEY_CODE_KP_B,
- [SDL_SCANCODE_KP_C] = Q_KEY_CODE_KP_C,
- [SDL_SCANCODE_KP_D] = Q_KEY_CODE_KP_D,
- [SDL_SCANCODE_KP_E] = Q_KEY_CODE_KP_E,
- [SDL_SCANCODE_KP_F] = Q_KEY_CODE_KP_F,
- [SDL_SCANCODE_KP_XOR] = Q_KEY_CODE_KP_XOR,
- [SDL_SCANCODE_KP_POWER] = Q_KEY_CODE_KP_POWER,
- [SDL_SCANCODE_KP_PERCENT] = Q_KEY_CODE_KP_PERCENT,
- [SDL_SCANCODE_KP_LESS] = Q_KEY_CODE_KP_LESS,
- [SDL_SCANCODE_KP_GREATER] = Q_KEY_CODE_KP_GREATER,
- [SDL_SCANCODE_KP_AMPERSAND] = Q_KEY_CODE_KP_AMPERSAND,
- [SDL_SCANCODE_KP_DBLAMPERSAND] = Q_KEY_CODE_KP_DBLAMPERSAND,
- [SDL_SCANCODE_KP_VERTICALBAR] = Q_KEY_CODE_KP_VERTICALBAR,
- [SDL_SCANCODE_KP_DBLVERTICALBAR] = Q_KEY_CODE_KP_DBLVERTICALBAR,
- [SDL_SCANCODE_KP_COLON] = Q_KEY_CODE_KP_COLON,
- [SDL_SCANCODE_KP_HASH] = Q_KEY_CODE_KP_HASH,
- [SDL_SCANCODE_KP_SPACE] = Q_KEY_CODE_KP_SPACE,
- [SDL_SCANCODE_KP_AT] = Q_KEY_CODE_KP_AT,
- [SDL_SCANCODE_KP_EXCLAM] = Q_KEY_CODE_KP_EXCLAM,
- [SDL_SCANCODE_KP_MEMSTORE] = Q_KEY_CODE_KP_MEMSTORE,
- [SDL_SCANCODE_KP_MEMRECALL] = Q_KEY_CODE_KP_MEMRECALL,
- [SDL_SCANCODE_KP_MEMCLEAR] = Q_KEY_CODE_KP_MEMCLEAR,
- [SDL_SCANCODE_KP_MEMADD] = Q_KEY_CODE_KP_MEMADD,
- [SDL_SCANCODE_KP_MEMSUBTRACT] = Q_KEY_CODE_KP_MEMSUBTRACT,
- [SDL_SCANCODE_KP_MEMMULTIPLY] = Q_KEY_CODE_KP_MEMMULTIPLY,
- [SDL_SCANCODE_KP_MEMDIVIDE] = Q_KEY_CODE_KP_MEMDIVIDE,
- [SDL_SCANCODE_KP_PLUSMINUS] = Q_KEY_CODE_KP_PLUSMINUS,
- [SDL_SCANCODE_KP_CLEAR] = Q_KEY_CODE_KP_CLEAR,
- [SDL_SCANCODE_KP_CLEARENTRY] = Q_KEY_CODE_KP_CLEARENTRY,
- [SDL_SCANCODE_KP_BINARY] = Q_KEY_CODE_KP_BINARY,
- [SDL_SCANCODE_KP_OCTAL] = Q_KEY_CODE_KP_OCTAL,
- [SDL_SCANCODE_KP_DECIMAL] = Q_KEY_CODE_KP_DECIMAL,
- [SDL_SCANCODE_KP_HEXADECIMAL] = Q_KEY_CODE_KP_HEXADECIMAL,
-#endif
- [SDL_SCANCODE_LCTRL] = Q_KEY_CODE_CTRL,
- [SDL_SCANCODE_LSHIFT] = Q_KEY_CODE_SHIFT,
- [SDL_SCANCODE_LALT] = Q_KEY_CODE_ALT,
- [SDL_SCANCODE_LGUI] = Q_KEY_CODE_META_L,
- [SDL_SCANCODE_RCTRL] = Q_KEY_CODE_CTRL_R,
- [SDL_SCANCODE_RSHIFT] = Q_KEY_CODE_SHIFT_R,
- [SDL_SCANCODE_RALT] = Q_KEY_CODE_ALT_R,
- [SDL_SCANCODE_RGUI] = Q_KEY_CODE_META_R,
-#if 0
- [SDL_SCANCODE_MODE] = Q_KEY_CODE_MODE,
- [SDL_SCANCODE_AUDIONEXT] = Q_KEY_CODE_AUDIONEXT,
- [SDL_SCANCODE_AUDIOPREV] = Q_KEY_CODE_AUDIOPREV,
- [SDL_SCANCODE_AUDIOSTOP] = Q_KEY_CODE_AUDIOSTOP,
- [SDL_SCANCODE_AUDIOPLAY] = Q_KEY_CODE_AUDIOPLAY,
- [SDL_SCANCODE_AUDIOMUTE] = Q_KEY_CODE_AUDIOMUTE,
- [SDL_SCANCODE_MEDIASELECT] = Q_KEY_CODE_MEDIASELECT,
- [SDL_SCANCODE_WWW] = Q_KEY_CODE_WWW,
- [SDL_SCANCODE_MAIL] = Q_KEY_CODE_MAIL,
- [SDL_SCANCODE_CALCULATOR] = Q_KEY_CODE_CALCULATOR,
- [SDL_SCANCODE_COMPUTER] = Q_KEY_CODE_COMPUTER,
- [SDL_SCANCODE_AC_SEARCH] = Q_KEY_CODE_AC_SEARCH,
- [SDL_SCANCODE_AC_HOME] = Q_KEY_CODE_AC_HOME,
- [SDL_SCANCODE_AC_BACK] = Q_KEY_CODE_AC_BACK,
- [SDL_SCANCODE_AC_FORWARD] = Q_KEY_CODE_AC_FORWARD,
- [SDL_SCANCODE_AC_STOP] = Q_KEY_CODE_AC_STOP,
- [SDL_SCANCODE_AC_REFRESH] = Q_KEY_CODE_AC_REFRESH,
- [SDL_SCANCODE_AC_BOOKMARKS] = Q_KEY_CODE_AC_BOOKMARKS,
- [SDL_SCANCODE_BRIGHTNESSDOWN] = Q_KEY_CODE_BRIGHTNESSDOWN,
- [SDL_SCANCODE_BRIGHTNESSUP] = Q_KEY_CODE_BRIGHTNESSUP,
- [SDL_SCANCODE_DISPLAYSWITCH] = Q_KEY_CODE_DISPLAYSWITCH,
- [SDL_SCANCODE_KBDILLUMTOGGLE] = Q_KEY_CODE_KBDILLUMTOGGLE,
- [SDL_SCANCODE_KBDILLUMDOWN] = Q_KEY_CODE_KBDILLUMDOWN,
- [SDL_SCANCODE_KBDILLUMUP] = Q_KEY_CODE_KBDILLUMUP,
- [SDL_SCANCODE_EJECT] = Q_KEY_CODE_EJECT,
- [SDL_SCANCODE_SLEEP] = Q_KEY_CODE_SLEEP,
- [SDL_SCANCODE_APP1] = Q_KEY_CODE_APP1,
- [SDL_SCANCODE_APP2] = Q_KEY_CODE_APP2,
-#endif
-};
diff --git a/qemu/ui/sdl2.c b/qemu/ui/sdl2.c
deleted file mode 100644
index d0424421e..000000000
--- a/qemu/ui/sdl2.c
+++ /dev/null
@@ -1,837 +0,0 @@
-/*
- * QEMU SDL display driver
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-/* Ported SDL 1.2 code to 2.0 by Dave Airlie. */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "ui/console.h"
-#include "ui/input.h"
-#include "ui/sdl2.h"
-#include "sysemu/sysemu.h"
-
-static int sdl2_num_outputs;
-static struct sdl2_console *sdl2_console;
-
-static SDL_Surface *guest_sprite_surface;
-static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
-
-static int gui_saved_grab;
-static int gui_fullscreen;
-static int gui_noframe;
-static int gui_key_modifier_pressed;
-static int gui_keysym;
-static int gui_grab_code = KMOD_LALT | KMOD_LCTRL;
-static SDL_Cursor *sdl_cursor_normal;
-static SDL_Cursor *sdl_cursor_hidden;
-static int absolute_enabled;
-static int guest_cursor;
-static int guest_x, guest_y;
-static SDL_Cursor *guest_sprite;
-static Notifier mouse_mode_notifier;
-
-#define SDL2_REFRESH_INTERVAL_BUSY 10
-#define SDL2_MAX_IDLE_COUNT (2 * GUI_REFRESH_INTERVAL_DEFAULT \
- / SDL2_REFRESH_INTERVAL_BUSY + 1)
-
-static void sdl_update_caption(struct sdl2_console *scon);
-
-static struct sdl2_console *get_scon_from_window(uint32_t window_id)
-{
- int i;
- for (i = 0; i < sdl2_num_outputs; i++) {
- if (sdl2_console[i].real_window == SDL_GetWindowFromID(window_id)) {
- return &sdl2_console[i];
- }
- }
- return NULL;
-}
-
-void sdl2_window_create(struct sdl2_console *scon)
-{
- int flags = 0;
-
- if (!scon->surface) {
- return;
- }
- assert(!scon->real_window);
-
- if (gui_fullscreen) {
- flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
- } else {
- flags |= SDL_WINDOW_RESIZABLE;
- }
- if (scon->hidden) {
- flags |= SDL_WINDOW_HIDDEN;
- }
-
- scon->real_window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED,
- SDL_WINDOWPOS_UNDEFINED,
- surface_width(scon->surface),
- surface_height(scon->surface),
- flags);
- scon->real_renderer = SDL_CreateRenderer(scon->real_window, -1, 0);
- if (scon->opengl) {
- scon->winctx = SDL_GL_GetCurrentContext();
- }
- sdl_update_caption(scon);
-}
-
-void sdl2_window_destroy(struct sdl2_console *scon)
-{
- if (!scon->real_window) {
- return;
- }
-
- SDL_DestroyRenderer(scon->real_renderer);
- scon->real_renderer = NULL;
- SDL_DestroyWindow(scon->real_window);
- scon->real_window = NULL;
-}
-
-void sdl2_window_resize(struct sdl2_console *scon)
-{
- if (!scon->real_window) {
- return;
- }
-
- SDL_SetWindowSize(scon->real_window,
- surface_width(scon->surface),
- surface_height(scon->surface));
-}
-
-static void sdl2_redraw(struct sdl2_console *scon)
-{
- if (scon->opengl) {
-#ifdef CONFIG_OPENGL
- sdl2_gl_redraw(scon);
-#endif
- } else {
- sdl2_2d_redraw(scon);
- }
-}
-
-static void sdl_update_caption(struct sdl2_console *scon)
-{
- char win_title[1024];
- char icon_title[1024];
- const char *status = "";
-
- if (!runstate_is_running()) {
- status = " [Stopped]";
- } else if (gui_grab) {
- if (alt_grab) {
- status = " - Press Ctrl-Alt-Shift to exit grab";
- } else if (ctrl_grab) {
- status = " - Press Right-Ctrl to exit grab";
- } else {
- status = " - Press Ctrl-Alt to exit grab";
- }
- }
-
- if (qemu_name) {
- snprintf(win_title, sizeof(win_title), "QEMU (%s-%d)%s", qemu_name,
- scon->idx, status);
- snprintf(icon_title, sizeof(icon_title), "QEMU (%s)", qemu_name);
- } else {
- snprintf(win_title, sizeof(win_title), "QEMU%s", status);
- snprintf(icon_title, sizeof(icon_title), "QEMU");
- }
-
- if (scon->real_window) {
- SDL_SetWindowTitle(scon->real_window, win_title);
- }
-}
-
-static void sdl_hide_cursor(void)
-{
- if (!cursor_hide) {
- return;
- }
-
- if (qemu_input_is_absolute()) {
- SDL_ShowCursor(1);
- SDL_SetCursor(sdl_cursor_hidden);
- } else {
- SDL_SetRelativeMouseMode(SDL_TRUE);
- }
-}
-
-static void sdl_show_cursor(void)
-{
- if (!cursor_hide) {
- return;
- }
-
- if (!qemu_input_is_absolute()) {
- SDL_SetRelativeMouseMode(SDL_FALSE);
- SDL_ShowCursor(1);
- if (guest_cursor &&
- (gui_grab || qemu_input_is_absolute() || absolute_enabled)) {
- SDL_SetCursor(guest_sprite);
- } else {
- SDL_SetCursor(sdl_cursor_normal);
- }
- }
-}
-
-static void sdl_grab_start(struct sdl2_console *scon)
-{
- QemuConsole *con = scon ? scon->dcl.con : NULL;
-
- if (!con || !qemu_console_is_graphic(con)) {
- return;
- }
- /*
- * If the application is not active, do not try to enter grab state. This
- * prevents 'SDL_WM_GrabInput(SDL_GRAB_ON)' from blocking all the
- * application (SDL bug).
- */
- if (!(SDL_GetWindowFlags(scon->real_window) & SDL_WINDOW_INPUT_FOCUS)) {
- return;
- }
- if (guest_cursor) {
- SDL_SetCursor(guest_sprite);
- if (!qemu_input_is_absolute() && !absolute_enabled) {
- SDL_WarpMouseInWindow(scon->real_window, guest_x, guest_y);
- }
- } else {
- sdl_hide_cursor();
- }
- SDL_SetWindowGrab(scon->real_window, SDL_TRUE);
- gui_grab = 1;
- sdl_update_caption(scon);
-}
-
-static void sdl_grab_end(struct sdl2_console *scon)
-{
- SDL_SetWindowGrab(scon->real_window, SDL_FALSE);
- gui_grab = 0;
- sdl_show_cursor();
- sdl_update_caption(scon);
-}
-
-static void absolute_mouse_grab(struct sdl2_console *scon)
-{
- int mouse_x, mouse_y;
- int scr_w, scr_h;
- SDL_GetMouseState(&mouse_x, &mouse_y);
- SDL_GetWindowSize(scon->real_window, &scr_w, &scr_h);
- if (mouse_x > 0 && mouse_x < scr_w - 1 &&
- mouse_y > 0 && mouse_y < scr_h - 1) {
- sdl_grab_start(scon);
- }
-}
-
-static void sdl_mouse_mode_change(Notifier *notify, void *data)
-{
- if (qemu_input_is_absolute()) {
- if (!absolute_enabled) {
- absolute_enabled = 1;
- absolute_mouse_grab(&sdl2_console[0]);
- }
- } else if (absolute_enabled) {
- if (!gui_fullscreen) {
- sdl_grab_end(&sdl2_console[0]);
- }
- absolute_enabled = 0;
- }
-}
-
-static void sdl_send_mouse_event(struct sdl2_console *scon, int dx, int dy,
- int x, int y, int state)
-{
- static uint32_t bmap[INPUT_BUTTON__MAX] = {
- [INPUT_BUTTON_LEFT] = SDL_BUTTON(SDL_BUTTON_LEFT),
- [INPUT_BUTTON_MIDDLE] = SDL_BUTTON(SDL_BUTTON_MIDDLE),
- [INPUT_BUTTON_RIGHT] = SDL_BUTTON(SDL_BUTTON_RIGHT),
- };
- static uint32_t prev_state;
-
- if (prev_state != state) {
- qemu_input_update_buttons(scon->dcl.con, bmap, prev_state, state);
- prev_state = state;
- }
-
- if (qemu_input_is_absolute()) {
- int scr_w, scr_h;
- int max_w = 0, max_h = 0;
- int off_x = 0, off_y = 0;
- int cur_off_x = 0, cur_off_y = 0;
- int i;
-
- for (i = 0; i < sdl2_num_outputs; i++) {
- struct sdl2_console *thiscon = &sdl2_console[i];
- if (thiscon->real_window && thiscon->surface) {
- SDL_GetWindowSize(thiscon->real_window, &scr_w, &scr_h);
- cur_off_x = thiscon->x;
- cur_off_y = thiscon->y;
- if (scr_w + cur_off_x > max_w) {
- max_w = scr_w + cur_off_x;
- }
- if (scr_h + cur_off_y > max_h) {
- max_h = scr_h + cur_off_y;
- }
- if (i == scon->idx) {
- off_x = cur_off_x;
- off_y = cur_off_y;
- }
- }
- }
- qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_X, off_x + x, max_w);
- qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_Y, off_y + y, max_h);
- } else {
- if (guest_cursor) {
- x -= guest_x;
- y -= guest_y;
- guest_x += x;
- guest_y += y;
- dx = x;
- dy = y;
- }
- qemu_input_queue_rel(scon->dcl.con, INPUT_AXIS_X, dx);
- qemu_input_queue_rel(scon->dcl.con, INPUT_AXIS_Y, dy);
- }
- qemu_input_event_sync();
-}
-
-static void toggle_full_screen(struct sdl2_console *scon)
-{
- gui_fullscreen = !gui_fullscreen;
- if (gui_fullscreen) {
- SDL_SetWindowFullscreen(scon->real_window,
- SDL_WINDOW_FULLSCREEN_DESKTOP);
- gui_saved_grab = gui_grab;
- sdl_grab_start(scon);
- } else {
- if (!gui_saved_grab) {
- sdl_grab_end(scon);
- }
- SDL_SetWindowFullscreen(scon->real_window, 0);
- }
- sdl2_redraw(scon);
-}
-
-static void handle_keydown(SDL_Event *ev)
-{
- int mod_state, win;
- struct sdl2_console *scon = get_scon_from_window(ev->key.windowID);
-
- if (alt_grab) {
- mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) ==
- (gui_grab_code | KMOD_LSHIFT);
- } else if (ctrl_grab) {
- mod_state = (SDL_GetModState() & KMOD_RCTRL) == KMOD_RCTRL;
- } else {
- mod_state = (SDL_GetModState() & gui_grab_code) == gui_grab_code;
- }
- gui_key_modifier_pressed = mod_state;
-
- if (gui_key_modifier_pressed) {
- switch (ev->key.keysym.scancode) {
- case SDL_SCANCODE_2:
- case SDL_SCANCODE_3:
- case SDL_SCANCODE_4:
- case SDL_SCANCODE_5:
- case SDL_SCANCODE_6:
- case SDL_SCANCODE_7:
- case SDL_SCANCODE_8:
- case SDL_SCANCODE_9:
- win = ev->key.keysym.scancode - SDL_SCANCODE_1;
- if (win < sdl2_num_outputs) {
- sdl2_console[win].hidden = !sdl2_console[win].hidden;
- if (sdl2_console[win].real_window) {
- if (sdl2_console[win].hidden) {
- SDL_HideWindow(sdl2_console[win].real_window);
- } else {
- SDL_ShowWindow(sdl2_console[win].real_window);
- }
- }
- gui_keysym = 1;
- }
- break;
- case SDL_SCANCODE_F:
- toggle_full_screen(scon);
- gui_keysym = 1;
- break;
- case SDL_SCANCODE_U:
- sdl2_window_destroy(scon);
- sdl2_window_create(scon);
- if (!scon->opengl) {
- /* re-create scon->texture */
- sdl2_2d_switch(&scon->dcl, scon->surface);
- }
- gui_keysym = 1;
- break;
-#if 0
- case SDL_SCANCODE_KP_PLUS:
- case SDL_SCANCODE_KP_MINUS:
- if (!gui_fullscreen) {
- int scr_w, scr_h;
- int width, height;
- SDL_GetWindowSize(scon->real_window, &scr_w, &scr_h);
-
- width = MAX(scr_w + (ev->key.keysym.scancode ==
- SDL_SCANCODE_KP_PLUS ? 50 : -50),
- 160);
- height = (surface_height(scon->surface) * width) /
- surface_width(scon->surface);
- fprintf(stderr, "%s: scale to %dx%d\n",
- __func__, width, height);
- sdl_scale(scon, width, height);
- sdl2_redraw(scon);
- gui_keysym = 1;
- }
-#endif
- default:
- break;
- }
- }
- if (!gui_keysym) {
- sdl2_process_key(scon, &ev->key);
- }
-}
-
-static void handle_keyup(SDL_Event *ev)
-{
- int mod_state;
- struct sdl2_console *scon = get_scon_from_window(ev->key.windowID);
-
- if (!alt_grab) {
- mod_state = (ev->key.keysym.mod & gui_grab_code);
- } else {
- mod_state = (ev->key.keysym.mod & (gui_grab_code | KMOD_LSHIFT));
- }
- if (!mod_state && gui_key_modifier_pressed) {
- gui_key_modifier_pressed = 0;
- if (gui_keysym == 0) {
- /* exit/enter grab if pressing Ctrl-Alt */
- if (!gui_grab) {
- sdl_grab_start(scon);
- } else if (!gui_fullscreen) {
- sdl_grab_end(scon);
- }
- /* SDL does not send back all the modifiers key, so we must
- * correct it. */
- sdl2_reset_keys(scon);
- return;
- }
- gui_keysym = 0;
- }
- if (!gui_keysym) {
- sdl2_process_key(scon, &ev->key);
- }
-}
-
-static void handle_textinput(SDL_Event *ev)
-{
- struct sdl2_console *scon = get_scon_from_window(ev->key.windowID);
- QemuConsole *con = scon ? scon->dcl.con : NULL;
-
- if (qemu_console_is_graphic(con)) {
- return;
- }
- kbd_put_string_console(con, ev->text.text, strlen(ev->text.text));
-}
-
-static void handle_mousemotion(SDL_Event *ev)
-{
- int max_x, max_y;
- struct sdl2_console *scon = get_scon_from_window(ev->key.windowID);
-
- if (qemu_input_is_absolute() || absolute_enabled) {
- int scr_w, scr_h;
- SDL_GetWindowSize(scon->real_window, &scr_w, &scr_h);
- max_x = scr_w - 1;
- max_y = scr_h - 1;
- if (gui_grab && (ev->motion.x == 0 || ev->motion.y == 0 ||
- ev->motion.x == max_x || ev->motion.y == max_y)) {
- sdl_grab_end(scon);
- }
- if (!gui_grab &&
- (ev->motion.x > 0 && ev->motion.x < max_x &&
- ev->motion.y > 0 && ev->motion.y < max_y)) {
- sdl_grab_start(scon);
- }
- }
- if (gui_grab || qemu_input_is_absolute() || absolute_enabled) {
- sdl_send_mouse_event(scon, ev->motion.xrel, ev->motion.yrel,
- ev->motion.x, ev->motion.y, ev->motion.state);
- }
-}
-
-static void handle_mousebutton(SDL_Event *ev)
-{
- int buttonstate = SDL_GetMouseState(NULL, NULL);
- SDL_MouseButtonEvent *bev;
- struct sdl2_console *scon = get_scon_from_window(ev->key.windowID);
-
- bev = &ev->button;
- if (!gui_grab && !qemu_input_is_absolute()) {
- if (ev->type == SDL_MOUSEBUTTONUP && bev->button == SDL_BUTTON_LEFT) {
- /* start grabbing all events */
- sdl_grab_start(scon);
- }
- } else {
- if (ev->type == SDL_MOUSEBUTTONDOWN) {
- buttonstate |= SDL_BUTTON(bev->button);
- } else {
- buttonstate &= ~SDL_BUTTON(bev->button);
- }
- sdl_send_mouse_event(scon, 0, 0, bev->x, bev->y, buttonstate);
- }
-}
-
-static void handle_mousewheel(SDL_Event *ev)
-{
- struct sdl2_console *scon = get_scon_from_window(ev->key.windowID);
- SDL_MouseWheelEvent *wev = &ev->wheel;
- InputButton btn;
-
- if (wev->y > 0) {
- btn = INPUT_BUTTON_WHEEL_UP;
- } else if (wev->y < 0) {
- btn = INPUT_BUTTON_WHEEL_DOWN;
- } else {
- return;
- }
-
- qemu_input_queue_btn(scon->dcl.con, btn, true);
- qemu_input_event_sync();
- qemu_input_queue_btn(scon->dcl.con, btn, false);
- qemu_input_event_sync();
-}
-
-static void handle_windowevent(SDL_Event *ev)
-{
- struct sdl2_console *scon = get_scon_from_window(ev->window.windowID);
-
- if (!scon) {
- return;
- }
-
- switch (ev->window.event) {
- case SDL_WINDOWEVENT_RESIZED:
- {
- QemuUIInfo info;
- memset(&info, 0, sizeof(info));
- info.width = ev->window.data1;
- info.height = ev->window.data2;
- dpy_set_ui_info(scon->dcl.con, &info);
- }
- sdl2_redraw(scon);
- break;
- case SDL_WINDOWEVENT_EXPOSED:
- sdl2_redraw(scon);
- break;
- case SDL_WINDOWEVENT_FOCUS_GAINED:
- case SDL_WINDOWEVENT_ENTER:
- if (!gui_grab && (qemu_input_is_absolute() || absolute_enabled)) {
- absolute_mouse_grab(scon);
- }
- break;
- case SDL_WINDOWEVENT_FOCUS_LOST:
- if (gui_grab && !gui_fullscreen) {
- sdl_grab_end(scon);
- }
- break;
- case SDL_WINDOWEVENT_RESTORED:
- update_displaychangelistener(&scon->dcl, GUI_REFRESH_INTERVAL_DEFAULT);
- break;
- case SDL_WINDOWEVENT_MINIMIZED:
- update_displaychangelistener(&scon->dcl, 500);
- break;
- case SDL_WINDOWEVENT_CLOSE:
- if (!no_quit) {
- no_shutdown = 0;
- qemu_system_shutdown_request();
- }
- break;
- case SDL_WINDOWEVENT_SHOWN:
- if (scon->hidden) {
- SDL_HideWindow(scon->real_window);
- }
- break;
- case SDL_WINDOWEVENT_HIDDEN:
- if (!scon->hidden) {
- SDL_ShowWindow(scon->real_window);
- }
- break;
- }
-}
-
-void sdl2_poll_events(struct sdl2_console *scon)
-{
- SDL_Event ev1, *ev = &ev1;
- int idle = 1;
-
- if (scon->last_vm_running != runstate_is_running()) {
- scon->last_vm_running = runstate_is_running();
- sdl_update_caption(scon);
- }
-
- while (SDL_PollEvent(ev)) {
- switch (ev->type) {
- case SDL_KEYDOWN:
- idle = 0;
- handle_keydown(ev);
- break;
- case SDL_KEYUP:
- idle = 0;
- handle_keyup(ev);
- break;
- case SDL_TEXTINPUT:
- idle = 0;
- handle_textinput(ev);
- break;
- case SDL_QUIT:
- if (!no_quit) {
- no_shutdown = 0;
- qemu_system_shutdown_request();
- }
- break;
- case SDL_MOUSEMOTION:
- idle = 0;
- handle_mousemotion(ev);
- break;
- case SDL_MOUSEBUTTONDOWN:
- case SDL_MOUSEBUTTONUP:
- idle = 0;
- handle_mousebutton(ev);
- break;
- case SDL_MOUSEWHEEL:
- idle = 0;
- handle_mousewheel(ev);
- break;
- case SDL_WINDOWEVENT:
- handle_windowevent(ev);
- break;
- default:
- break;
- }
- }
-
- if (idle) {
- if (scon->idle_counter < SDL2_MAX_IDLE_COUNT) {
- scon->idle_counter++;
- if (scon->idle_counter >= SDL2_MAX_IDLE_COUNT) {
- scon->dcl.update_interval = GUI_REFRESH_INTERVAL_DEFAULT;
- }
- }
- } else {
- scon->idle_counter = 0;
- scon->dcl.update_interval = SDL2_REFRESH_INTERVAL_BUSY;
- }
-}
-
-static void sdl_mouse_warp(DisplayChangeListener *dcl,
- int x, int y, int on)
-{
- struct sdl2_console *scon = container_of(dcl, struct sdl2_console, dcl);
- if (on) {
- if (!guest_cursor) {
- sdl_show_cursor();
- }
- if (gui_grab || qemu_input_is_absolute() || absolute_enabled) {
- SDL_SetCursor(guest_sprite);
- if (!qemu_input_is_absolute() && !absolute_enabled) {
- SDL_WarpMouseInWindow(scon->real_window, x, y);
- }
- }
- } else if (gui_grab) {
- sdl_hide_cursor();
- }
- guest_cursor = on;
- guest_x = x, guest_y = y;
-}
-
-static void sdl_mouse_define(DisplayChangeListener *dcl,
- QEMUCursor *c)
-{
-
- if (guest_sprite) {
- SDL_FreeCursor(guest_sprite);
- }
-
- if (guest_sprite_surface) {
- SDL_FreeSurface(guest_sprite_surface);
- }
-
- guest_sprite_surface =
- SDL_CreateRGBSurfaceFrom(c->data, c->width, c->height, 32, c->width * 4,
- 0xff0000, 0x00ff00, 0xff, 0xff000000);
-
- if (!guest_sprite_surface) {
- fprintf(stderr, "Failed to make rgb surface from %p\n", c);
- return;
- }
- guest_sprite = SDL_CreateColorCursor(guest_sprite_surface,
- c->hot_x, c->hot_y);
- if (!guest_sprite) {
- fprintf(stderr, "Failed to make color cursor from %p\n", c);
- return;
- }
- if (guest_cursor &&
- (gui_grab || qemu_input_is_absolute() || absolute_enabled)) {
- SDL_SetCursor(guest_sprite);
- }
-}
-
-static void sdl_cleanup(void)
-{
- if (guest_sprite) {
- SDL_FreeCursor(guest_sprite);
- }
- SDL_QuitSubSystem(SDL_INIT_VIDEO);
-}
-
-static const DisplayChangeListenerOps dcl_2d_ops = {
- .dpy_name = "sdl2-2d",
- .dpy_gfx_update = sdl2_2d_update,
- .dpy_gfx_switch = sdl2_2d_switch,
- .dpy_gfx_check_format = sdl2_2d_check_format,
- .dpy_refresh = sdl2_2d_refresh,
- .dpy_mouse_set = sdl_mouse_warp,
- .dpy_cursor_define = sdl_mouse_define,
-};
-
-#ifdef CONFIG_OPENGL
-static const DisplayChangeListenerOps dcl_gl_ops = {
- .dpy_name = "sdl2-gl",
- .dpy_gfx_update = sdl2_gl_update,
- .dpy_gfx_switch = sdl2_gl_switch,
- .dpy_gfx_check_format = console_gl_check_format,
- .dpy_refresh = sdl2_gl_refresh,
- .dpy_mouse_set = sdl_mouse_warp,
- .dpy_cursor_define = sdl_mouse_define,
-
- .dpy_gl_ctx_create = sdl2_gl_create_context,
- .dpy_gl_ctx_destroy = sdl2_gl_destroy_context,
- .dpy_gl_ctx_make_current = sdl2_gl_make_context_current,
- .dpy_gl_ctx_get_current = sdl2_gl_get_current_context,
- .dpy_gl_scanout = sdl2_gl_scanout,
- .dpy_gl_update = sdl2_gl_scanout_flush,
-};
-#endif
-
-void sdl_display_early_init(int opengl)
-{
- switch (opengl) {
- case -1: /* default */
- case 0: /* off */
- break;
- case 1: /* on */
-#ifdef CONFIG_OPENGL
- display_opengl = 1;
-#endif
- break;
- default:
- g_assert_not_reached();
- break;
- }
-}
-
-void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
-{
- int flags;
- uint8_t data = 0;
- char *filename;
- int i;
-
- if (no_frame) {
- gui_noframe = 1;
- }
-
-#ifdef __linux__
- /* on Linux, SDL may use fbcon|directfb|svgalib when run without
- * accessible $DISPLAY to open X11 window. This is often the case
- * when qemu is run using sudo. But in this case, and when actually
- * run in X11 environment, SDL fights with X11 for the video card,
- * making current display unavailable, often until reboot.
- * So make x11 the default SDL video driver if this variable is unset.
- * This is a bit hackish but saves us from bigger problem.
- * Maybe it's a good idea to fix this in SDL instead.
- */
- setenv("SDL_VIDEODRIVER", "x11", 0);
-#endif
-
- flags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE;
- if (SDL_Init(flags)) {
- fprintf(stderr, "Could not initialize SDL(%s) - exiting\n",
- SDL_GetError());
- exit(1);
- }
- SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "1");
-
- for (i = 0;; i++) {
- QemuConsole *con = qemu_console_lookup_by_index(i);
- if (!con) {
- break;
- }
- }
- sdl2_num_outputs = i;
- sdl2_console = g_new0(struct sdl2_console, sdl2_num_outputs);
- for (i = 0; i < sdl2_num_outputs; i++) {
- QemuConsole *con = qemu_console_lookup_by_index(i);
- if (!qemu_console_is_graphic(con)) {
- sdl2_console[i].hidden = true;
- }
- sdl2_console[i].idx = i;
-#ifdef CONFIG_OPENGL
- sdl2_console[i].opengl = display_opengl;
- sdl2_console[i].dcl.ops = display_opengl ? &dcl_gl_ops : &dcl_2d_ops;
-#else
- sdl2_console[i].opengl = 0;
- sdl2_console[i].dcl.ops = &dcl_2d_ops;
-#endif
- sdl2_console[i].dcl.con = con;
- register_displaychangelistener(&sdl2_console[i].dcl);
- }
-
- /* Load a 32x32x4 image. White pixels are transparent. */
- filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "qemu-icon.bmp");
- if (filename) {
- SDL_Surface *image = SDL_LoadBMP(filename);
- if (image) {
- uint32_t colorkey = SDL_MapRGB(image->format, 255, 255, 255);
- SDL_SetColorKey(image, SDL_TRUE, colorkey);
- SDL_SetWindowIcon(sdl2_console[0].real_window, image);
- }
- g_free(filename);
- }
-
- if (full_screen) {
- gui_fullscreen = 1;
- sdl_grab_start(0);
- }
-
- mouse_mode_notifier.notify = sdl_mouse_mode_change;
- qemu_add_mouse_mode_change_notifier(&mouse_mode_notifier);
-
- gui_grab = 0;
-
- sdl_cursor_hidden = SDL_CreateCursor(&data, &data, 8, 1, 0, 0);
- sdl_cursor_normal = SDL_GetCursor();
-
- atexit(sdl_cleanup);
-}
diff --git a/qemu/ui/sdl_keysym.h b/qemu/ui/sdl_keysym.h
deleted file mode 100644
index 599d9fc64..000000000
--- a/qemu/ui/sdl_keysym.h
+++ /dev/null
@@ -1,278 +0,0 @@
-
-#include "keymaps.h"
-
-static const name2keysym_t name2keysym[]={
-/* ascii */
- { "space", 0x020},
- { "exclam", 0x021},
- { "quotedbl", 0x022},
- { "numbersign", 0x023},
- { "dollar", 0x024},
- { "percent", 0x025},
- { "ampersand", 0x026},
- { "apostrophe", 0x027},
- { "parenleft", 0x028},
- { "parenright", 0x029},
- { "asterisk", 0x02a},
- { "plus", 0x02b},
- { "comma", 0x02c},
- { "minus", 0x02d},
- { "period", 0x02e},
- { "slash", 0x02f},
- { "0", 0x030},
- { "1", 0x031},
- { "2", 0x032},
- { "3", 0x033},
- { "4", 0x034},
- { "5", 0x035},
- { "6", 0x036},
- { "7", 0x037},
- { "8", 0x038},
- { "9", 0x039},
- { "colon", 0x03a},
- { "semicolon", 0x03b},
- { "less", 0x03c},
- { "equal", 0x03d},
- { "greater", 0x03e},
- { "question", 0x03f},
- { "at", 0x040},
- { "A", 0x041},
- { "B", 0x042},
- { "C", 0x043},
- { "D", 0x044},
- { "E", 0x045},
- { "F", 0x046},
- { "G", 0x047},
- { "H", 0x048},
- { "I", 0x049},
- { "J", 0x04a},
- { "K", 0x04b},
- { "L", 0x04c},
- { "M", 0x04d},
- { "N", 0x04e},
- { "O", 0x04f},
- { "P", 0x050},
- { "Q", 0x051},
- { "R", 0x052},
- { "S", 0x053},
- { "T", 0x054},
- { "U", 0x055},
- { "V", 0x056},
- { "W", 0x057},
- { "X", 0x058},
- { "Y", 0x059},
- { "Z", 0x05a},
- { "bracketleft", 0x05b},
- { "backslash", 0x05c},
- { "bracketright", 0x05d},
- { "asciicircum", 0x05e},
- { "underscore", 0x05f},
- { "grave", 0x060},
- { "a", 0x061},
- { "b", 0x062},
- { "c", 0x063},
- { "d", 0x064},
- { "e", 0x065},
- { "f", 0x066},
- { "g", 0x067},
- { "h", 0x068},
- { "i", 0x069},
- { "j", 0x06a},
- { "k", 0x06b},
- { "l", 0x06c},
- { "m", 0x06d},
- { "n", 0x06e},
- { "o", 0x06f},
- { "p", 0x070},
- { "q", 0x071},
- { "r", 0x072},
- { "s", 0x073},
- { "t", 0x074},
- { "u", 0x075},
- { "v", 0x076},
- { "w", 0x077},
- { "x", 0x078},
- { "y", 0x079},
- { "z", 0x07a},
- { "braceleft", 0x07b},
- { "bar", 0x07c},
- { "braceright", 0x07d},
- { "asciitilde", 0x07e},
-
-/* latin 1 extensions */
-{ "nobreakspace", 0x0a0},
-{ "exclamdown", 0x0a1},
-{ "cent", 0x0a2},
-{ "sterling", 0x0a3},
-{ "currency", 0x0a4},
-{ "yen", 0x0a5},
-{ "brokenbar", 0x0a6},
-{ "section", 0x0a7},
-{ "diaeresis", 0x0a8},
-{ "copyright", 0x0a9},
-{ "ordfeminine", 0x0aa},
-{ "guillemotleft", 0x0ab},
-{ "notsign", 0x0ac},
-{ "hyphen", 0x0ad},
-{ "registered", 0x0ae},
-{ "macron", 0x0af},
-{ "degree", 0x0b0},
-{ "plusminus", 0x0b1},
-{ "twosuperior", 0x0b2},
-{ "threesuperior", 0x0b3},
-{ "acute", 0x0b4},
-{ "mu", 0x0b5},
-{ "paragraph", 0x0b6},
-{ "periodcentered", 0x0b7},
-{ "cedilla", 0x0b8},
-{ "onesuperior", 0x0b9},
-{ "masculine", 0x0ba},
-{ "guillemotright", 0x0bb},
-{ "onequarter", 0x0bc},
-{ "onehalf", 0x0bd},
-{ "threequarters", 0x0be},
-{ "questiondown", 0x0bf},
-{ "Agrave", 0x0c0},
-{ "Aacute", 0x0c1},
-{ "Acircumflex", 0x0c2},
-{ "Atilde", 0x0c3},
-{ "Adiaeresis", 0x0c4},
-{ "Aring", 0x0c5},
-{ "AE", 0x0c6},
-{ "Ccedilla", 0x0c7},
-{ "Egrave", 0x0c8},
-{ "Eacute", 0x0c9},
-{ "Ecircumflex", 0x0ca},
-{ "Ediaeresis", 0x0cb},
-{ "Igrave", 0x0cc},
-{ "Iacute", 0x0cd},
-{ "Icircumflex", 0x0ce},
-{ "Idiaeresis", 0x0cf},
-{ "ETH", 0x0d0},
-{ "Eth", 0x0d0},
-{ "Ntilde", 0x0d1},
-{ "Ograve", 0x0d2},
-{ "Oacute", 0x0d3},
-{ "Ocircumflex", 0x0d4},
-{ "Otilde", 0x0d5},
-{ "Odiaeresis", 0x0d6},
-{ "multiply", 0x0d7},
-{ "Ooblique", 0x0d8},
-{ "Oslash", 0x0d8},
-{ "Ugrave", 0x0d9},
-{ "Uacute", 0x0da},
-{ "Ucircumflex", 0x0db},
-{ "Udiaeresis", 0x0dc},
-{ "Yacute", 0x0dd},
-{ "THORN", 0x0de},
-{ "Thorn", 0x0de},
-{ "ssharp", 0x0df},
-{ "agrave", 0x0e0},
-{ "aacute", 0x0e1},
-{ "acircumflex", 0x0e2},
-{ "atilde", 0x0e3},
-{ "adiaeresis", 0x0e4},
-{ "aring", 0x0e5},
-{ "ae", 0x0e6},
-{ "ccedilla", 0x0e7},
-{ "egrave", 0x0e8},
-{ "eacute", 0x0e9},
-{ "ecircumflex", 0x0ea},
-{ "ediaeresis", 0x0eb},
-{ "igrave", 0x0ec},
-{ "iacute", 0x0ed},
-{ "icircumflex", 0x0ee},
-{ "idiaeresis", 0x0ef},
-{ "eth", 0x0f0},
-{ "ntilde", 0x0f1},
-{ "ograve", 0x0f2},
-{ "oacute", 0x0f3},
-{ "ocircumflex", 0x0f4},
-{ "otilde", 0x0f5},
-{ "odiaeresis", 0x0f6},
-{ "division", 0x0f7},
-{ "oslash", 0x0f8},
-{ "ooblique", 0x0f8},
-{ "ugrave", 0x0f9},
-{ "uacute", 0x0fa},
-{ "ucircumflex", 0x0fb},
-{ "udiaeresis", 0x0fc},
-{ "yacute", 0x0fd},
-{ "thorn", 0x0fe},
-{ "ydiaeresis", 0x0ff},
-#if SDL_MAJOR_VERSION == 1
-{"EuroSign", SDLK_EURO},
-
- /* modifiers */
-{"Control_L", SDLK_LCTRL},
-{"Control_R", SDLK_RCTRL},
-{"Alt_L", SDLK_LALT},
-{"Alt_R", SDLK_RALT},
-{"Caps_Lock", SDLK_CAPSLOCK},
-{"Meta_L", SDLK_LMETA},
-{"Meta_R", SDLK_RMETA},
-{"Shift_L", SDLK_LSHIFT},
-{"Shift_R", SDLK_RSHIFT},
-{"Super_L", SDLK_LSUPER},
-{"Super_R", SDLK_RSUPER},
-
- /* special keys */
-{"BackSpace", SDLK_BACKSPACE},
-{"Tab", SDLK_TAB},
-{"Return", SDLK_RETURN},
-{"Right", SDLK_RIGHT},
-{"Left", SDLK_LEFT},
-{"Up", SDLK_UP},
-{"Down", SDLK_DOWN},
-{"Page_Down", SDLK_PAGEDOWN},
-{"Page_Up", SDLK_PAGEUP},
-{"Insert", SDLK_INSERT},
-{"Delete", SDLK_DELETE},
-{"Home", SDLK_HOME},
-{"End", SDLK_END},
-{"Scroll_Lock", SDLK_SCROLLOCK},
-{"F1", SDLK_F1},
-{"F2", SDLK_F2},
-{"F3", SDLK_F3},
-{"F4", SDLK_F4},
-{"F5", SDLK_F5},
-{"F6", SDLK_F6},
-{"F7", SDLK_F7},
-{"F8", SDLK_F8},
-{"F9", SDLK_F9},
-{"F10", SDLK_F10},
-{"F11", SDLK_F11},
-{"F12", SDLK_F12},
-{"F13", SDLK_F13},
-{"F14", SDLK_F14},
-{"F15", SDLK_F15},
-{"Sys_Req", SDLK_SYSREQ},
-{"KP_0", SDLK_KP0},
-{"KP_1", SDLK_KP1},
-{"KP_2", SDLK_KP2},
-{"KP_3", SDLK_KP3},
-{"KP_4", SDLK_KP4},
-{"KP_5", SDLK_KP5},
-{"KP_6", SDLK_KP6},
-{"KP_7", SDLK_KP7},
-{"KP_8", SDLK_KP8},
-{"KP_9", SDLK_KP9},
-{"KP_Add", SDLK_KP_PLUS},
-{"KP_Decimal", SDLK_KP_PERIOD},
-{"KP_Divide", SDLK_KP_DIVIDE},
-{"KP_Enter", SDLK_KP_ENTER},
-{"KP_Equal", SDLK_KP_EQUALS},
-{"KP_Multiply", SDLK_KP_MULTIPLY},
-{"KP_Subtract", SDLK_KP_MINUS},
-{"help", SDLK_HELP},
-{"Menu", SDLK_MENU},
-{"Power", SDLK_POWER},
-{"Print", SDLK_PRINT},
-{"Mode_switch", SDLK_MODE},
-{"Multi_Key", SDLK_COMPOSE},
-{"Num_Lock", SDLK_NUMLOCK},
-{"Pause", SDLK_PAUSE},
-{"Escape", SDLK_ESCAPE},
-#endif
-{NULL, 0},
-};
diff --git a/qemu/ui/sdl_zoom.c b/qemu/ui/sdl_zoom.c
deleted file mode 100644
index 72622c264..000000000
--- a/qemu/ui/sdl_zoom.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * SDL_zoom - surface scaling
- *
- * Copyright (c) 2009 Citrix Systems, Inc.
- *
- * Derived from: SDL_rotozoom, LGPL (c) A. Schiffler from the SDL_gfx library.
- * Modifications by Stefano Stabellini.
- *
- * This work is licensed under the terms of the GNU GPL version 2.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu/osdep.h"
-#include "sdl_zoom.h"
-#include <glib.h>
-
-static void sdl_zoom_rgb16(SDL_Surface *src, SDL_Surface *dst, int smooth,
- SDL_Rect *dst_rect);
-static void sdl_zoom_rgb32(SDL_Surface *src, SDL_Surface *dst, int smooth,
- SDL_Rect *dst_rect);
-
-#define BPP 32
-#include "sdl_zoom_template.h"
-#undef BPP
-#define BPP 16
-#include "sdl_zoom_template.h"
-#undef BPP
-
-int sdl_zoom_blit(SDL_Surface *src_sfc, SDL_Surface *dst_sfc, int smooth,
- SDL_Rect *in_rect)
-{
- SDL_Rect zoom, src_rect;
- int extra;
-
- /* Grow the size of the modified rectangle to avoid edge artefacts */
- src_rect.x = (in_rect->x > 0) ? (in_rect->x - 1) : 0;
- src_rect.y = (in_rect->y > 0) ? (in_rect->y - 1) : 0;
-
- src_rect.w = in_rect->w + 1;
- if (src_rect.x + src_rect.w > src_sfc->w)
- src_rect.w = src_sfc->w - src_rect.x;
-
- src_rect.h = in_rect->h + 1;
- if (src_rect.y + src_rect.h > src_sfc->h)
- src_rect.h = src_sfc->h - src_rect.y;
-
- /* (x,y) : round down */
- zoom.x = (int)(((float)(src_rect.x * dst_sfc->w)) / (float)(src_sfc->w));
- zoom.y = (int)(((float)(src_rect.y * dst_sfc->h)) / (float)(src_sfc->h));
-
- /* (w,h) : round up */
- zoom.w = (int)( ((double)((src_rect.w * dst_sfc->w) + (src_sfc->w - 1))) /
- (double)(src_sfc->w));
-
- zoom.h = (int)( ((double)((src_rect.h * dst_sfc->h) + (src_sfc->h - 1))) /
- (double)(src_sfc->h));
-
- /* Account for any (x,y) rounding by adding one-source-pixel's worth
- * of destination pixels and then edge checking.
- */
-
- extra = ((dst_sfc->w-1) / src_sfc->w) + 1;
-
- if ((zoom.x + zoom.w) < (dst_sfc->w - extra))
- zoom.w += extra;
- else
- zoom.w = dst_sfc->w - zoom.x;
-
- extra = ((dst_sfc->h-1) / src_sfc->h) + 1;
-
- if ((zoom.y + zoom.h) < (dst_sfc->h - extra))
- zoom.h += extra;
- else
- zoom.h = dst_sfc->h - zoom.y;
-
- /* The rectangle (zoom.x, zoom.y, zoom.w, zoom.h) is the area on the
- * destination surface that needs to be updated.
- */
- if (src_sfc->format->BitsPerPixel == 32)
- sdl_zoom_rgb32(src_sfc, dst_sfc, smooth, &zoom);
- else if (src_sfc->format->BitsPerPixel == 16)
- sdl_zoom_rgb16(src_sfc, dst_sfc, smooth, &zoom);
- else {
- fprintf(stderr, "pixel format not supported\n");
- return -1;
- }
-
- /* Return the rectangle of the update to the caller */
- *in_rect = zoom;
-
- return 0;
-}
-
diff --git a/qemu/ui/sdl_zoom.h b/qemu/ui/sdl_zoom.h
deleted file mode 100644
index 74955bc94..000000000
--- a/qemu/ui/sdl_zoom.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * SDL_zoom - surface scaling
- *
- * Copyright (c) 2009 Citrix Systems, Inc.
- *
- * Derived from: SDL_rotozoom, LGPL (c) A. Schiffler from the SDL_gfx library.
- * Modifications by Stefano Stabellini.
- *
- * This work is licensed under the terms of the GNU GPL version 2.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#ifndef SDL_zoom_h
-#define SDL_zoom_h
-
-#include <SDL.h>
-
-#define SMOOTHING_OFF 0
-#define SMOOTHING_ON 1
-
-int sdl_zoom_blit(SDL_Surface *src_sfc, SDL_Surface *dst_sfc,
- int smooth, SDL_Rect *src_rect);
-
-#endif /* SDL_zoom_h */
diff --git a/qemu/ui/sdl_zoom_template.h b/qemu/ui/sdl_zoom_template.h
deleted file mode 100644
index 3bb508b51..000000000
--- a/qemu/ui/sdl_zoom_template.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * SDL_zoom_template - surface scaling
- *
- * Copyright (c) 2009 Citrix Systems, Inc.
- *
- * Derived from: SDL_rotozoom, LGPL (c) A. Schiffler from the SDL_gfx library.
- * Modifications by Stefano Stabellini.
- *
- * This work is licensed under the terms of the GNU GPL version 2.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#if BPP == 16
-#define SDL_TYPE Uint16
-#elif BPP == 32
-#define SDL_TYPE Uint32
-#else
-#error unsupport depth
-#endif
-
-/*
- * Simple helper functions to make the code looks nicer
- *
- * Assume spf = source SDL_PixelFormat
- * dpf = dest SDL_PixelFormat
- *
- */
-#define getRed(color) (((color) & spf->Rmask) >> spf->Rshift)
-#define getGreen(color) (((color) & spf->Gmask) >> spf->Gshift)
-#define getBlue(color) (((color) & spf->Bmask) >> spf->Bshift)
-#define getAlpha(color) (((color) & spf->Amask) >> spf->Ashift)
-
-#define setRed(r, pcolor) do { \
- *pcolor = ((*pcolor) & (~(dpf->Rmask))) + \
- (((r) & (dpf->Rmask >> dpf->Rshift)) << dpf->Rshift); \
-} while (0);
-
-#define setGreen(g, pcolor) do { \
- *pcolor = ((*pcolor) & (~(dpf->Gmask))) + \
- (((g) & (dpf->Gmask >> dpf->Gshift)) << dpf->Gshift); \
-} while (0);
-
-#define setBlue(b, pcolor) do { \
- *pcolor = ((*pcolor) & (~(dpf->Bmask))) + \
- (((b) & (dpf->Bmask >> dpf->Bshift)) << dpf->Bshift); \
-} while (0);
-
-#define setAlpha(a, pcolor) do { \
- *pcolor = ((*pcolor) & (~(dpf->Amask))) + \
- (((a) & (dpf->Amask >> dpf->Ashift)) << dpf->Ashift); \
-} while (0);
-
-static void glue(sdl_zoom_rgb, BPP)(SDL_Surface *src, SDL_Surface *dst, int smooth,
- SDL_Rect *dst_rect)
-{
- int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, ex, ey, t1, t2, sstep, sstep_jump;
- SDL_TYPE *c00, *c01, *c10, *c11, *sp, *csp, *dp;
- int d_gap;
- SDL_PixelFormat *spf = src->format;
- SDL_PixelFormat *dpf = dst->format;
-
- if (smooth) {
- /* For interpolation: assume source dimension is one pixel.
- * Smaller here to avoid overflow on right and bottom edge.
- */
- sx = (int) (65536.0 * (float) (src->w - 1) / (float) dst->w);
- sy = (int) (65536.0 * (float) (src->h - 1) / (float) dst->h);
- } else {
- sx = (int) (65536.0 * (float) src->w / (float) dst->w);
- sy = (int) (65536.0 * (float) src->h / (float) dst->h);
- }
-
- sax = g_new(int, dst->w + 1);
- say = g_new(int, dst->h + 1);
-
- sp = csp = (SDL_TYPE *) src->pixels;
- dp = (SDL_TYPE *) (dst->pixels + dst_rect->y * dst->pitch +
- dst_rect->x * dst->format->BytesPerPixel);
-
- csx = 0;
- csax = sax;
- for (x = 0; x <= dst->w; x++) {
- *csax = csx;
- csax++;
- csx &= 0xffff;
- csx += sx;
- }
- csy = 0;
- csay = say;
- for (y = 0; y <= dst->h; y++) {
- *csay = csy;
- csay++;
- csy &= 0xffff;
- csy += sy;
- }
-
- d_gap = dst->pitch - dst_rect->w * dst->format->BytesPerPixel;
-
- if (smooth) {
- csay = say;
- for (y = 0; y < dst_rect->y; y++) {
- csay++;
- sstep = (*csay >> 16) * src->pitch;
- csp = (SDL_TYPE *) ((Uint8 *) csp + sstep);
- }
-
- /* Calculate sstep_jump */
- csax = sax;
- sstep_jump = 0;
- for (x = 0; x < dst_rect->x; x++) {
- csax++;
- sstep = (*csax >> 16);
- sstep_jump += sstep;
- }
-
- for (y = 0; y < dst_rect->h ; y++) {
- /* Setup colour source pointers */
- c00 = csp + sstep_jump;
- c01 = c00 + 1;
- c10 = (SDL_TYPE *) ((Uint8 *) csp + src->pitch) + sstep_jump;
- c11 = c10 + 1;
- csax = sax + dst_rect->x;
-
- for (x = 0; x < dst_rect->w; x++) {
-
- /* Interpolate colours */
- ex = (*csax & 0xffff);
- ey = (*csay & 0xffff);
- t1 = ((((getRed(*c01) - getRed(*c00)) * ex) >> 16) +
- getRed(*c00)) & (dpf->Rmask >> dpf->Rshift);
- t2 = ((((getRed(*c11) - getRed(*c10)) * ex) >> 16) +
- getRed(*c10)) & (dpf->Rmask >> dpf->Rshift);
- setRed((((t2 - t1) * ey) >> 16) + t1, dp);
- t1 = ((((getGreen(*c01) - getGreen(*c00)) * ex) >> 16) +
- getGreen(*c00)) & (dpf->Gmask >> dpf->Gshift);
- t2 = ((((getGreen(*c11) - getGreen(*c10)) * ex) >> 16) +
- getGreen(*c10)) & (dpf->Gmask >> dpf->Gshift);
- setGreen((((t2 - t1) * ey) >> 16) + t1, dp);
- t1 = ((((getBlue(*c01) - getBlue(*c00)) * ex) >> 16) +
- getBlue(*c00)) & (dpf->Bmask >> dpf->Bshift);
- t2 = ((((getBlue(*c11) - getBlue(*c10)) * ex) >> 16) +
- getBlue(*c10)) & (dpf->Bmask >> dpf->Bshift);
- setBlue((((t2 - t1) * ey) >> 16) + t1, dp);
- t1 = ((((getAlpha(*c01) - getAlpha(*c00)) * ex) >> 16) +
- getAlpha(*c00)) & (dpf->Amask >> dpf->Ashift);
- t2 = ((((getAlpha(*c11) - getAlpha(*c10)) * ex) >> 16) +
- getAlpha(*c10)) & (dpf->Amask >> dpf->Ashift);
- setAlpha((((t2 - t1) * ey) >> 16) + t1, dp);
-
- /* Advance source pointers */
- csax++;
- sstep = (*csax >> 16);
- c00 += sstep;
- c01 += sstep;
- c10 += sstep;
- c11 += sstep;
- /* Advance destination pointer */
- dp++;
- }
- /* Advance source pointer */
- csay++;
- csp = (SDL_TYPE *) ((Uint8 *) csp + (*csay >> 16) * src->pitch);
- /* Advance destination pointers */
- dp = (SDL_TYPE *) ((Uint8 *) dp + d_gap);
- }
-
-
- } else {
- csay = say;
-
- for (y = 0; y < dst_rect->y; y++) {
- csay++;
- sstep = (*csay >> 16) * src->pitch;
- csp = (SDL_TYPE *) ((Uint8 *) csp + sstep);
- }
-
- /* Calculate sstep_jump */
- csax = sax;
- sstep_jump = 0;
- for (x = 0; x < dst_rect->x; x++) {
- csax++;
- sstep = (*csax >> 16);
- sstep_jump += sstep;
- }
-
- for (y = 0 ; y < dst_rect->h ; y++) {
- sp = csp + sstep_jump;
- csax = sax + dst_rect->x;
-
- for (x = 0; x < dst_rect->w; x++) {
-
- /* Draw */
- *dp = *sp;
-
- /* Advance source pointers */
- csax++;
- sstep = (*csax >> 16);
- sp += sstep;
-
- /* Advance destination pointer */
- dp++;
- }
- /* Advance source pointers */
- csay++;
- sstep = (*csay >> 16) * src->pitch;
- csp = (SDL_TYPE *) ((Uint8 *) csp + sstep);
-
- /* Advance destination pointer */
- dp = (SDL_TYPE *) ((Uint8 *) dp + d_gap);
- }
- }
-
- g_free(sax);
- g_free(say);
-}
-
-#undef SDL_TYPE
-
diff --git a/qemu/ui/shader.c b/qemu/ui/shader.c
deleted file mode 100644
index 9264009b8..000000000
--- a/qemu/ui/shader.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * QEMU opengl shader helper functions
- *
- * Copyright (c) 2014 Red Hat
- *
- * Authors:
- * Gerd Hoffmann <kraxel@redhat.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "ui/shader.h"
-
-/* ---------------------------------------------------------------------- */
-
-GLuint qemu_gl_init_texture_blit(GLint texture_blit_prog)
-{
- static const GLfloat in_position[] = {
- -1, -1,
- 1, -1,
- -1, 1,
- 1, 1,
- };
- GLint l_position;
- GLuint vao, buffer;
-
- glGenVertexArrays(1, &vao);
- glBindVertexArray(vao);
-
- /* this is the VBO that holds the vertex data */
- glGenBuffers(1, &buffer);
- glBindBuffer(GL_ARRAY_BUFFER, buffer);
- glBufferData(GL_ARRAY_BUFFER, sizeof(in_position), in_position,
- GL_STATIC_DRAW);
-
- l_position = glGetAttribLocation(texture_blit_prog, "in_position");
- glVertexAttribPointer(l_position, 2, GL_FLOAT, GL_FALSE, 0, 0);
- glEnableVertexAttribArray(l_position);
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindVertexArray(0);
-
- return vao;
-}
-
-void qemu_gl_run_texture_blit(GLint texture_blit_prog,
- GLint texture_blit_vao)
-{
- glUseProgram(texture_blit_prog);
- glBindVertexArray(texture_blit_vao);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-}
-
-/* ---------------------------------------------------------------------- */
-
-GLuint qemu_gl_create_compile_shader(GLenum type, const GLchar *src)
-{
- GLuint shader;
- GLint status, length;
- char *errmsg;
-
- shader = glCreateShader(type);
- glShaderSource(shader, 1, &src, 0);
- glCompileShader(shader);
-
- glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
- if (!status) {
- glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
- errmsg = malloc(length);
- glGetShaderInfoLog(shader, length, &length, errmsg);
- fprintf(stderr, "%s: compile %s error\n%s\n", __func__,
- (type == GL_VERTEX_SHADER) ? "vertex" : "fragment",
- errmsg);
- free(errmsg);
- return 0;
- }
- return shader;
-}
-
-GLuint qemu_gl_create_link_program(GLuint vert, GLuint frag)
-{
- GLuint program;
- GLint status, length;
- char *errmsg;
-
- program = glCreateProgram();
- glAttachShader(program, vert);
- glAttachShader(program, frag);
- glLinkProgram(program);
-
- glGetProgramiv(program, GL_LINK_STATUS, &status);
- if (!status) {
- glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
- errmsg = malloc(length);
- glGetProgramInfoLog(program, length, &length, errmsg);
- fprintf(stderr, "%s: link program: %s\n", __func__, errmsg);
- free(errmsg);
- return 0;
- }
- return program;
-}
-
-GLuint qemu_gl_create_compile_link_program(const GLchar *vert_src,
- const GLchar *frag_src)
-{
- GLuint vert_shader, frag_shader, program;
-
- vert_shader = qemu_gl_create_compile_shader(GL_VERTEX_SHADER, vert_src);
- frag_shader = qemu_gl_create_compile_shader(GL_FRAGMENT_SHADER, frag_src);
- if (!vert_shader || !frag_shader) {
- return 0;
- }
-
- program = qemu_gl_create_link_program(vert_shader, frag_shader);
- glDeleteShader(vert_shader);
- glDeleteShader(frag_shader);
-
- return program;
-}
diff --git a/qemu/ui/shader/texture-blit.frag b/qemu/ui/shader/texture-blit.frag
deleted file mode 100644
index bfa202c22..000000000
--- a/qemu/ui/shader/texture-blit.frag
+++ /dev/null
@@ -1,10 +0,0 @@
-
-#version 300 es
-
-uniform sampler2D image;
-in mediump vec2 ex_tex_coord;
-out mediump vec4 out_frag_color;
-
-void main(void) {
- out_frag_color = texture(image, ex_tex_coord);
-}
diff --git a/qemu/ui/shader/texture-blit.vert b/qemu/ui/shader/texture-blit.vert
deleted file mode 100644
index 6fe2744d6..000000000
--- a/qemu/ui/shader/texture-blit.vert
+++ /dev/null
@@ -1,10 +0,0 @@
-
-#version 300 es
-
-in vec2 in_position;
-out vec2 ex_tex_coord;
-
-void main(void) {
- gl_Position = vec4(in_position, 0.0, 1.0);
- ex_tex_coord = vec2(1.0 + in_position.x, 1.0 - in_position.y) * 0.5;
-}
diff --git a/qemu/ui/spice-core.c b/qemu/ui/spice-core.c
deleted file mode 100644
index 61db3c18b..000000000
--- a/qemu/ui/spice-core.c
+++ /dev/null
@@ -1,953 +0,0 @@
-/*
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include <spice.h>
-
-#include <netdb.h>
-#include "sysemu/sysemu.h"
-
-#include "qemu-common.h"
-#include "ui/qemu-spice.h"
-#include "qemu/error-report.h"
-#include "qemu/thread.h"
-#include "qemu/timer.h"
-#include "qemu/queue.h"
-#include "qemu-x509.h"
-#include "qemu/sockets.h"
-#include "qmp-commands.h"
-#include "qapi/qmp/qint.h"
-#include "qapi/qmp/qbool.h"
-#include "qapi/qmp/qstring.h"
-#include "qapi/qmp/qjson.h"
-#include "qemu/notify.h"
-#include "migration/migration.h"
-#include "hw/hw.h"
-#include "ui/spice-display.h"
-#include "qapi-event.h"
-
-/* core bits */
-
-static SpiceServer *spice_server;
-static Notifier migration_state;
-static const char *auth = "spice";
-static char *auth_passwd;
-static time_t auth_expires = TIME_MAX;
-static int spice_migration_completed;
-static int spice_display_is_running;
-static int spice_have_target_host;
-int using_spice = 0;
-
-static QemuThread me;
-
-struct SpiceTimer {
- QEMUTimer *timer;
- QTAILQ_ENTRY(SpiceTimer) next;
-};
-static QTAILQ_HEAD(, SpiceTimer) timers = QTAILQ_HEAD_INITIALIZER(timers);
-
-static SpiceTimer *timer_add(SpiceTimerFunc func, void *opaque)
-{
- SpiceTimer *timer;
-
- timer = g_malloc0(sizeof(*timer));
- timer->timer = timer_new_ms(QEMU_CLOCK_REALTIME, func, opaque);
- QTAILQ_INSERT_TAIL(&timers, timer, next);
- return timer;
-}
-
-static void timer_start(SpiceTimer *timer, uint32_t ms)
-{
- timer_mod(timer->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + ms);
-}
-
-static void timer_cancel(SpiceTimer *timer)
-{
- timer_del(timer->timer);
-}
-
-static void timer_remove(SpiceTimer *timer)
-{
- timer_del(timer->timer);
- timer_free(timer->timer);
- QTAILQ_REMOVE(&timers, timer, next);
- g_free(timer);
-}
-
-struct SpiceWatch {
- int fd;
- int event_mask;
- SpiceWatchFunc func;
- void *opaque;
- QTAILQ_ENTRY(SpiceWatch) next;
-};
-static QTAILQ_HEAD(, SpiceWatch) watches = QTAILQ_HEAD_INITIALIZER(watches);
-
-static void watch_read(void *opaque)
-{
- SpiceWatch *watch = opaque;
- watch->func(watch->fd, SPICE_WATCH_EVENT_READ, watch->opaque);
-}
-
-static void watch_write(void *opaque)
-{
- SpiceWatch *watch = opaque;
- watch->func(watch->fd, SPICE_WATCH_EVENT_WRITE, watch->opaque);
-}
-
-static void watch_update_mask(SpiceWatch *watch, int event_mask)
-{
- IOHandler *on_read = NULL;
- IOHandler *on_write = NULL;
-
- watch->event_mask = event_mask;
- if (watch->event_mask & SPICE_WATCH_EVENT_READ) {
- on_read = watch_read;
- }
- if (watch->event_mask & SPICE_WATCH_EVENT_WRITE) {
- on_write = watch_write;
- }
- qemu_set_fd_handler(watch->fd, on_read, on_write, watch);
-}
-
-static SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, void *opaque)
-{
- SpiceWatch *watch;
-
- watch = g_malloc0(sizeof(*watch));
- watch->fd = fd;
- watch->func = func;
- watch->opaque = opaque;
- QTAILQ_INSERT_TAIL(&watches, watch, next);
-
- watch_update_mask(watch, event_mask);
- return watch;
-}
-
-static void watch_remove(SpiceWatch *watch)
-{
- qemu_set_fd_handler(watch->fd, NULL, NULL, NULL);
- QTAILQ_REMOVE(&watches, watch, next);
- g_free(watch);
-}
-
-typedef struct ChannelList ChannelList;
-struct ChannelList {
- SpiceChannelEventInfo *info;
- QTAILQ_ENTRY(ChannelList) link;
-};
-static QTAILQ_HEAD(, ChannelList) channel_list = QTAILQ_HEAD_INITIALIZER(channel_list);
-
-static void channel_list_add(SpiceChannelEventInfo *info)
-{
- ChannelList *item;
-
- item = g_malloc0(sizeof(*item));
- item->info = info;
- QTAILQ_INSERT_TAIL(&channel_list, item, link);
-}
-
-static void channel_list_del(SpiceChannelEventInfo *info)
-{
- ChannelList *item;
-
- QTAILQ_FOREACH(item, &channel_list, link) {
- if (item->info != info) {
- continue;
- }
- QTAILQ_REMOVE(&channel_list, item, link);
- g_free(item);
- return;
- }
-}
-
-static void add_addr_info(SpiceBasicInfo *info, struct sockaddr *addr, int len)
-{
- char host[NI_MAXHOST], port[NI_MAXSERV];
-
- getnameinfo(addr, len, host, sizeof(host), port, sizeof(port),
- NI_NUMERICHOST | NI_NUMERICSERV);
-
- info->host = g_strdup(host);
- info->port = g_strdup(port);
- info->family = inet_netfamily(addr->sa_family);
-}
-
-static void add_channel_info(SpiceChannel *sc, SpiceChannelEventInfo *info)
-{
- int tls = info->flags & SPICE_CHANNEL_EVENT_FLAG_TLS;
-
- sc->connection_id = info->connection_id;
- sc->channel_type = info->type;
- sc->channel_id = info->id;
- sc->tls = !!tls;
-}
-
-static void channel_event(int event, SpiceChannelEventInfo *info)
-{
- SpiceServerInfo *server = g_malloc0(sizeof(*server));
- SpiceChannel *client = g_malloc0(sizeof(*client));
-
- /*
- * Spice server might have called us from spice worker thread
- * context (happens on display channel disconnects). Spice should
- * not do that. It isn't that easy to fix it in spice and even
- * when it is fixed we still should cover the already released
- * spice versions. So detect that we've been called from another
- * thread and grab the iothread lock if so before calling qemu
- * functions.
- */
- bool need_lock = !qemu_thread_is_self(&me);
- if (need_lock) {
- qemu_mutex_lock_iothread();
- }
-
- if (info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT) {
- add_addr_info(qapi_SpiceChannel_base(client),
- (struct sockaddr *)&info->paddr_ext,
- info->plen_ext);
- add_addr_info(qapi_SpiceServerInfo_base(server),
- (struct sockaddr *)&info->laddr_ext,
- info->llen_ext);
- } else {
- error_report("spice: %s, extended address is expected",
- __func__);
- }
-
- switch (event) {
- case SPICE_CHANNEL_EVENT_CONNECTED:
- qapi_event_send_spice_connected(qapi_SpiceServerInfo_base(server),
- qapi_SpiceChannel_base(client),
- &error_abort);
- break;
- case SPICE_CHANNEL_EVENT_INITIALIZED:
- if (auth) {
- server->has_auth = true;
- server->auth = g_strdup(auth);
- }
- add_channel_info(client, info);
- channel_list_add(info);
- qapi_event_send_spice_initialized(server, client, &error_abort);
- break;
- case SPICE_CHANNEL_EVENT_DISCONNECTED:
- channel_list_del(info);
- qapi_event_send_spice_disconnected(qapi_SpiceServerInfo_base(server),
- qapi_SpiceChannel_base(client),
- &error_abort);
- break;
- default:
- break;
- }
-
- if (need_lock) {
- qemu_mutex_unlock_iothread();
- }
-
- qapi_free_SpiceServerInfo(server);
- qapi_free_SpiceChannel(client);
-}
-
-static SpiceCoreInterface core_interface = {
- .base.type = SPICE_INTERFACE_CORE,
- .base.description = "qemu core services",
- .base.major_version = SPICE_INTERFACE_CORE_MAJOR,
- .base.minor_version = SPICE_INTERFACE_CORE_MINOR,
-
- .timer_add = timer_add,
- .timer_start = timer_start,
- .timer_cancel = timer_cancel,
- .timer_remove = timer_remove,
-
- .watch_add = watch_add,
- .watch_update_mask = watch_update_mask,
- .watch_remove = watch_remove,
-
- .channel_event = channel_event,
-};
-
-static void migrate_connect_complete_cb(SpiceMigrateInstance *sin);
-static void migrate_end_complete_cb(SpiceMigrateInstance *sin);
-
-static const SpiceMigrateInterface migrate_interface = {
- .base.type = SPICE_INTERFACE_MIGRATION,
- .base.description = "migration",
- .base.major_version = SPICE_INTERFACE_MIGRATION_MAJOR,
- .base.minor_version = SPICE_INTERFACE_MIGRATION_MINOR,
- .migrate_connect_complete = migrate_connect_complete_cb,
- .migrate_end_complete = migrate_end_complete_cb,
-};
-
-static SpiceMigrateInstance spice_migrate;
-
-static void migrate_connect_complete_cb(SpiceMigrateInstance *sin)
-{
- /* nothing, but libspice-server expects this cb being present. */
-}
-
-static void migrate_end_complete_cb(SpiceMigrateInstance *sin)
-{
- qapi_event_send_spice_migrate_completed(&error_abort);
- spice_migration_completed = true;
-}
-
-/* config string parsing */
-
-static int name2enum(const char *string, const char *table[], int entries)
-{
- int i;
-
- if (string) {
- for (i = 0; i < entries; i++) {
- if (!table[i]) {
- continue;
- }
- if (strcmp(string, table[i]) != 0) {
- continue;
- }
- return i;
- }
- }
- return -1;
-}
-
-static int parse_name(const char *string, const char *optname,
- const char *table[], int entries)
-{
- int value = name2enum(string, table, entries);
-
- if (value != -1) {
- return value;
- }
- error_report("spice: invalid %s: %s", optname, string);
- exit(1);
-}
-
-static const char *stream_video_names[] = {
- [ SPICE_STREAM_VIDEO_OFF ] = "off",
- [ SPICE_STREAM_VIDEO_ALL ] = "all",
- [ SPICE_STREAM_VIDEO_FILTER ] = "filter",
-};
-#define parse_stream_video(_name) \
- parse_name(_name, "stream video control", \
- stream_video_names, ARRAY_SIZE(stream_video_names))
-
-static const char *compression_names[] = {
- [ SPICE_IMAGE_COMPRESS_OFF ] = "off",
- [ SPICE_IMAGE_COMPRESS_AUTO_GLZ ] = "auto_glz",
- [ SPICE_IMAGE_COMPRESS_AUTO_LZ ] = "auto_lz",
- [ SPICE_IMAGE_COMPRESS_QUIC ] = "quic",
- [ SPICE_IMAGE_COMPRESS_GLZ ] = "glz",
- [ SPICE_IMAGE_COMPRESS_LZ ] = "lz",
-};
-#define parse_compression(_name) \
- parse_name(_name, "image compression", \
- compression_names, ARRAY_SIZE(compression_names))
-
-static const char *wan_compression_names[] = {
- [ SPICE_WAN_COMPRESSION_AUTO ] = "auto",
- [ SPICE_WAN_COMPRESSION_NEVER ] = "never",
- [ SPICE_WAN_COMPRESSION_ALWAYS ] = "always",
-};
-#define parse_wan_compression(_name) \
- parse_name(_name, "wan compression", \
- wan_compression_names, ARRAY_SIZE(wan_compression_names))
-
-/* functions for the rest of qemu */
-
-static SpiceChannelList *qmp_query_spice_channels(void)
-{
- SpiceChannelList *cur_item = NULL, *head = NULL;
- ChannelList *item;
-
- QTAILQ_FOREACH(item, &channel_list, link) {
- SpiceChannelList *chan;
- char host[NI_MAXHOST], port[NI_MAXSERV];
- struct sockaddr *paddr;
- socklen_t plen;
-
- assert(item->info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT);
-
- chan = g_malloc0(sizeof(*chan));
- chan->value = g_malloc0(sizeof(*chan->value));
-
- paddr = (struct sockaddr *)&item->info->paddr_ext;
- plen = item->info->plen_ext;
- getnameinfo(paddr, plen,
- host, sizeof(host), port, sizeof(port),
- NI_NUMERICHOST | NI_NUMERICSERV);
- chan->value->host = g_strdup(host);
- chan->value->port = g_strdup(port);
- chan->value->family = inet_netfamily(paddr->sa_family);
-
- chan->value->connection_id = item->info->connection_id;
- chan->value->channel_type = item->info->type;
- chan->value->channel_id = item->info->id;
- chan->value->tls = item->info->flags & SPICE_CHANNEL_EVENT_FLAG_TLS;
-
- /* XXX: waiting for the qapi to support GSList */
- if (!cur_item) {
- head = cur_item = chan;
- } else {
- cur_item->next = chan;
- cur_item = chan;
- }
- }
-
- return head;
-}
-
-static QemuOptsList qemu_spice_opts = {
- .name = "spice",
- .head = QTAILQ_HEAD_INITIALIZER(qemu_spice_opts.head),
- .desc = {
- {
- .name = "port",
- .type = QEMU_OPT_NUMBER,
- },{
- .name = "tls-port",
- .type = QEMU_OPT_NUMBER,
- },{
- .name = "addr",
- .type = QEMU_OPT_STRING,
- },{
- .name = "ipv4",
- .type = QEMU_OPT_BOOL,
- },{
- .name = "ipv6",
- .type = QEMU_OPT_BOOL,
-#ifdef SPICE_ADDR_FLAG_UNIX_ONLY
- },{
- .name = "unix",
- .type = QEMU_OPT_BOOL,
-#endif
- },{
- .name = "password",
- .type = QEMU_OPT_STRING,
- },{
- .name = "disable-ticketing",
- .type = QEMU_OPT_BOOL,
- },{
- .name = "disable-copy-paste",
- .type = QEMU_OPT_BOOL,
- },{
- .name = "disable-agent-file-xfer",
- .type = QEMU_OPT_BOOL,
- },{
- .name = "sasl",
- .type = QEMU_OPT_BOOL,
- },{
- .name = "x509-dir",
- .type = QEMU_OPT_STRING,
- },{
- .name = "x509-key-file",
- .type = QEMU_OPT_STRING,
- },{
- .name = "x509-key-password",
- .type = QEMU_OPT_STRING,
- },{
- .name = "x509-cert-file",
- .type = QEMU_OPT_STRING,
- },{
- .name = "x509-cacert-file",
- .type = QEMU_OPT_STRING,
- },{
- .name = "x509-dh-key-file",
- .type = QEMU_OPT_STRING,
- },{
- .name = "tls-ciphers",
- .type = QEMU_OPT_STRING,
- },{
- .name = "tls-channel",
- .type = QEMU_OPT_STRING,
- },{
- .name = "plaintext-channel",
- .type = QEMU_OPT_STRING,
- },{
- .name = "image-compression",
- .type = QEMU_OPT_STRING,
- },{
- .name = "jpeg-wan-compression",
- .type = QEMU_OPT_STRING,
- },{
- .name = "zlib-glz-wan-compression",
- .type = QEMU_OPT_STRING,
- },{
- .name = "streaming-video",
- .type = QEMU_OPT_STRING,
- },{
- .name = "agent-mouse",
- .type = QEMU_OPT_BOOL,
- },{
- .name = "playback-compression",
- .type = QEMU_OPT_BOOL,
- },{
- .name = "seamless-migration",
- .type = QEMU_OPT_BOOL,
-#ifdef HAVE_SPICE_GL
- },{
- .name = "gl",
- .type = QEMU_OPT_BOOL,
-#endif
- },
- { /* end of list */ }
- },
-};
-
-SpiceInfo *qmp_query_spice(Error **errp)
-{
- QemuOpts *opts = QTAILQ_FIRST(&qemu_spice_opts.head);
- int port, tls_port;
- const char *addr;
- SpiceInfo *info;
- unsigned int major;
- unsigned int minor;
- unsigned int micro;
-
- info = g_malloc0(sizeof(*info));
-
- if (!spice_server || !opts) {
- info->enabled = false;
- return info;
- }
-
- info->enabled = true;
- info->migrated = spice_migration_completed;
-
- addr = qemu_opt_get(opts, "addr");
- port = qemu_opt_get_number(opts, "port", 0);
- tls_port = qemu_opt_get_number(opts, "tls-port", 0);
-
- info->has_auth = true;
- info->auth = g_strdup(auth);
-
- info->has_host = true;
- info->host = g_strdup(addr ? addr : "*");
-
- info->has_compiled_version = true;
- major = (SPICE_SERVER_VERSION & 0xff0000) >> 16;
- minor = (SPICE_SERVER_VERSION & 0xff00) >> 8;
- micro = SPICE_SERVER_VERSION & 0xff;
- info->compiled_version = g_strdup_printf("%d.%d.%d", major, minor, micro);
-
- if (port) {
- info->has_port = true;
- info->port = port;
- }
- if (tls_port) {
- info->has_tls_port = true;
- info->tls_port = tls_port;
- }
-
- info->mouse_mode = spice_server_is_server_mouse(spice_server) ?
- SPICE_QUERY_MOUSE_MODE_SERVER :
- SPICE_QUERY_MOUSE_MODE_CLIENT;
-
- /* for compatibility with the original command */
- info->has_channels = true;
- info->channels = qmp_query_spice_channels();
-
- return info;
-}
-
-static void migration_state_notifier(Notifier *notifier, void *data)
-{
- MigrationState *s = data;
-
- if (!spice_have_target_host) {
- return;
- }
-
- if (migration_in_setup(s)) {
- spice_server_migrate_start(spice_server);
- } else if (migration_has_finished(s) ||
- migration_in_postcopy_after_devices(s)) {
- spice_server_migrate_end(spice_server, true);
- spice_have_target_host = false;
- } else if (migration_has_failed(s)) {
- spice_server_migrate_end(spice_server, false);
- spice_have_target_host = false;
- }
-}
-
-int qemu_spice_migrate_info(const char *hostname, int port, int tls_port,
- const char *subject)
-{
- int ret;
-
- ret = spice_server_migrate_connect(spice_server, hostname,
- port, tls_port, subject);
- spice_have_target_host = true;
- return ret;
-}
-
-static int add_channel(void *opaque, const char *name, const char *value,
- Error **errp)
-{
- int security = 0;
- int rc;
-
- if (strcmp(name, "tls-channel") == 0) {
- int *tls_port = opaque;
- if (!*tls_port) {
- error_report("spice: tried to setup tls-channel"
- " without specifying a TLS port");
- exit(1);
- }
- security = SPICE_CHANNEL_SECURITY_SSL;
- }
- if (strcmp(name, "plaintext-channel") == 0) {
- security = SPICE_CHANNEL_SECURITY_NONE;
- }
- if (security == 0) {
- return 0;
- }
- if (strcmp(value, "default") == 0) {
- rc = spice_server_set_channel_security(spice_server, NULL, security);
- } else {
- rc = spice_server_set_channel_security(spice_server, value, security);
- }
- if (rc != 0) {
- error_report("spice: failed to set channel security for %s", value);
- exit(1);
- }
- return 0;
-}
-
-static void vm_change_state_handler(void *opaque, int running,
- RunState state)
-{
- if (running) {
- qemu_spice_display_start();
- } else {
- qemu_spice_display_stop();
- }
-}
-
-void qemu_spice_init(void)
-{
- QemuOpts *opts = QTAILQ_FIRST(&qemu_spice_opts.head);
- const char *password, *str, *x509_dir, *addr,
- *x509_key_password = NULL,
- *x509_dh_file = NULL,
- *tls_ciphers = NULL;
- char *x509_key_file = NULL,
- *x509_cert_file = NULL,
- *x509_cacert_file = NULL;
- int port, tls_port, addr_flags;
- spice_image_compression_t compression;
- spice_wan_compression_t wan_compr;
- bool seamless_migration;
-
- qemu_thread_get_self(&me);
-
- if (!opts) {
- return;
- }
- port = qemu_opt_get_number(opts, "port", 0);
- tls_port = qemu_opt_get_number(opts, "tls-port", 0);
- if (port < 0 || port > 65535) {
- error_report("spice port is out of range");
- exit(1);
- }
- if (tls_port < 0 || tls_port > 65535) {
- error_report("spice tls-port is out of range");
- exit(1);
- }
- password = qemu_opt_get(opts, "password");
-
- if (tls_port) {
- x509_dir = qemu_opt_get(opts, "x509-dir");
- if (!x509_dir) {
- x509_dir = ".";
- }
-
- str = qemu_opt_get(opts, "x509-key-file");
- if (str) {
- x509_key_file = g_strdup(str);
- } else {
- x509_key_file = g_strdup_printf("%s/%s", x509_dir,
- X509_SERVER_KEY_FILE);
- }
-
- str = qemu_opt_get(opts, "x509-cert-file");
- if (str) {
- x509_cert_file = g_strdup(str);
- } else {
- x509_cert_file = g_strdup_printf("%s/%s", x509_dir,
- X509_SERVER_CERT_FILE);
- }
-
- str = qemu_opt_get(opts, "x509-cacert-file");
- if (str) {
- x509_cacert_file = g_strdup(str);
- } else {
- x509_cacert_file = g_strdup_printf("%s/%s", x509_dir,
- X509_CA_CERT_FILE);
- }
-
- x509_key_password = qemu_opt_get(opts, "x509-key-password");
- x509_dh_file = qemu_opt_get(opts, "x509-dh-key-file");
- tls_ciphers = qemu_opt_get(opts, "tls-ciphers");
- }
-
- addr = qemu_opt_get(opts, "addr");
- addr_flags = 0;
- if (qemu_opt_get_bool(opts, "ipv4", 0)) {
- addr_flags |= SPICE_ADDR_FLAG_IPV4_ONLY;
- } else if (qemu_opt_get_bool(opts, "ipv6", 0)) {
- addr_flags |= SPICE_ADDR_FLAG_IPV6_ONLY;
-#ifdef SPICE_ADDR_FLAG_UNIX_ONLY
- } else if (qemu_opt_get_bool(opts, "unix", 0)) {
- addr_flags |= SPICE_ADDR_FLAG_UNIX_ONLY;
-#endif
- }
-
- spice_server = spice_server_new();
- spice_server_set_addr(spice_server, addr ? addr : "", addr_flags);
- if (port) {
- spice_server_set_port(spice_server, port);
- }
- if (tls_port) {
- spice_server_set_tls(spice_server, tls_port,
- x509_cacert_file,
- x509_cert_file,
- x509_key_file,
- x509_key_password,
- x509_dh_file,
- tls_ciphers);
- }
- if (password) {
- qemu_spice_set_passwd(password, false, false);
- }
- if (qemu_opt_get_bool(opts, "sasl", 0)) {
- if (spice_server_set_sasl(spice_server, 1) == -1) {
- error_report("spice: failed to enable sasl");
- exit(1);
- }
- auth = "sasl";
- }
- if (qemu_opt_get_bool(opts, "disable-ticketing", 0)) {
- auth = "none";
- spice_server_set_noauth(spice_server);
- }
-
- if (qemu_opt_get_bool(opts, "disable-copy-paste", 0)) {
- spice_server_set_agent_copypaste(spice_server, false);
- }
-
- if (qemu_opt_get_bool(opts, "disable-agent-file-xfer", 0)) {
-#if SPICE_SERVER_VERSION >= 0x000c04
- spice_server_set_agent_file_xfer(spice_server, false);
-#else
- error_report("this qemu build does not support the "
- "\"disable-agent-file-xfer\" option");
- exit(1);
-#endif
- }
-
- compression = SPICE_IMAGE_COMPRESS_AUTO_GLZ;
- str = qemu_opt_get(opts, "image-compression");
- if (str) {
- compression = parse_compression(str);
- }
- spice_server_set_image_compression(spice_server, compression);
-
- wan_compr = SPICE_WAN_COMPRESSION_AUTO;
- str = qemu_opt_get(opts, "jpeg-wan-compression");
- if (str) {
- wan_compr = parse_wan_compression(str);
- }
- spice_server_set_jpeg_compression(spice_server, wan_compr);
-
- wan_compr = SPICE_WAN_COMPRESSION_AUTO;
- str = qemu_opt_get(opts, "zlib-glz-wan-compression");
- if (str) {
- wan_compr = parse_wan_compression(str);
- }
- spice_server_set_zlib_glz_compression(spice_server, wan_compr);
-
- str = qemu_opt_get(opts, "streaming-video");
- if (str) {
- int streaming_video = parse_stream_video(str);
- spice_server_set_streaming_video(spice_server, streaming_video);
- } else {
- spice_server_set_streaming_video(spice_server, SPICE_STREAM_VIDEO_OFF);
- }
-
- spice_server_set_agent_mouse
- (spice_server, qemu_opt_get_bool(opts, "agent-mouse", 1));
- spice_server_set_playback_compression
- (spice_server, qemu_opt_get_bool(opts, "playback-compression", 1));
-
- qemu_opt_foreach(opts, add_channel, &tls_port, NULL);
-
- spice_server_set_name(spice_server, qemu_name);
- spice_server_set_uuid(spice_server, qemu_uuid);
-
- seamless_migration = qemu_opt_get_bool(opts, "seamless-migration", 0);
- spice_server_set_seamless_migration(spice_server, seamless_migration);
- spice_server_set_sasl_appname(spice_server, "qemu");
- if (spice_server_init(spice_server, &core_interface) != 0) {
- error_report("failed to initialize spice server");
- exit(1);
- };
- using_spice = 1;
-
- migration_state.notify = migration_state_notifier;
- add_migration_state_change_notifier(&migration_state);
- spice_migrate.base.sif = &migrate_interface.base;
- qemu_spice_add_interface(&spice_migrate.base);
-
- qemu_spice_input_init();
- qemu_spice_audio_init();
-
- qemu_add_vm_change_state_handler(vm_change_state_handler, NULL);
- qemu_spice_display_stop();
-
- g_free(x509_key_file);
- g_free(x509_cert_file);
- g_free(x509_cacert_file);
-
-#if SPICE_SERVER_VERSION >= 0x000c02
- qemu_spice_register_ports();
-#endif
-
-#ifdef HAVE_SPICE_GL
- if (qemu_opt_get_bool(opts, "gl", 0)) {
- if ((port != 0) || (tls_port != 0)) {
- error_report("SPICE GL support is local-only for now and "
- "incompatible with -spice port/tls-port");
- exit(1);
- }
- if (egl_rendernode_init() == 0) {
- display_opengl = 1;
- }
- }
-#endif
-}
-
-int qemu_spice_add_interface(SpiceBaseInstance *sin)
-{
- if (!spice_server) {
- if (QTAILQ_FIRST(&qemu_spice_opts.head) != NULL) {
- error_report("Oops: spice configured but not active");
- exit(1);
- }
- /*
- * Create a spice server instance.
- * It does *not* listen on the network.
- * It handles QXL local rendering only.
- *
- * With a command line like '-vnc :0 -vga qxl' you'll end up here.
- */
- spice_server = spice_server_new();
- spice_server_set_sasl_appname(spice_server, "qemu");
- spice_server_init(spice_server, &core_interface);
- qemu_add_vm_change_state_handler(vm_change_state_handler, NULL);
- }
-
- return spice_server_add_interface(spice_server, sin);
-}
-
-static GSList *spice_consoles;
-
-bool qemu_spice_have_display_interface(QemuConsole *con)
-{
- if (g_slist_find(spice_consoles, con)) {
- return true;
- }
- return false;
-}
-
-int qemu_spice_add_display_interface(QXLInstance *qxlin, QemuConsole *con)
-{
- if (g_slist_find(spice_consoles, con)) {
- return -1;
- }
- qxlin->id = qemu_console_get_index(con);
- spice_consoles = g_slist_append(spice_consoles, con);
- return qemu_spice_add_interface(&qxlin->base);
-}
-
-static int qemu_spice_set_ticket(bool fail_if_conn, bool disconnect_if_conn)
-{
- time_t lifetime, now = time(NULL);
- char *passwd;
-
- if (now < auth_expires) {
- passwd = auth_passwd;
- lifetime = (auth_expires - now);
- if (lifetime > INT_MAX) {
- lifetime = INT_MAX;
- }
- } else {
- passwd = NULL;
- lifetime = 1;
- }
- return spice_server_set_ticket(spice_server, passwd, lifetime,
- fail_if_conn, disconnect_if_conn);
-}
-
-int qemu_spice_set_passwd(const char *passwd,
- bool fail_if_conn, bool disconnect_if_conn)
-{
- if (strcmp(auth, "spice") != 0) {
- return -1;
- }
-
- g_free(auth_passwd);
- auth_passwd = g_strdup(passwd);
- return qemu_spice_set_ticket(fail_if_conn, disconnect_if_conn);
-}
-
-int qemu_spice_set_pw_expire(time_t expires)
-{
- auth_expires = expires;
- return qemu_spice_set_ticket(false, false);
-}
-
-int qemu_spice_display_add_client(int csock, int skipauth, int tls)
-{
- if (tls) {
- return spice_server_add_ssl_client(spice_server, csock, skipauth);
- } else {
- return spice_server_add_client(spice_server, csock, skipauth);
- }
-}
-
-void qemu_spice_display_start(void)
-{
- spice_display_is_running = true;
- spice_server_vm_start(spice_server);
-}
-
-void qemu_spice_display_stop(void)
-{
- spice_server_vm_stop(spice_server);
- spice_display_is_running = false;
-}
-
-int qemu_spice_display_is_running(SimpleSpiceDisplay *ssd)
-{
- return spice_display_is_running;
-}
-
-static void spice_register_config(void)
-{
- qemu_add_opts(&qemu_spice_opts);
-}
-opts_init(spice_register_config);
diff --git a/qemu/ui/spice-display.c b/qemu/ui/spice-display.c
deleted file mode 100644
index 242ab5f46..000000000
--- a/qemu/ui/spice-display.c
+++ /dev/null
@@ -1,936 +0,0 @@
-/*
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "ui/qemu-spice.h"
-#include "qemu/timer.h"
-#include "qemu/queue.h"
-#include "ui/console.h"
-#include "sysemu/sysemu.h"
-#include "trace.h"
-
-#include "ui/spice-display.h"
-
-static int debug = 0;
-
-static void GCC_FMT_ATTR(2, 3) dprint(int level, const char *fmt, ...)
-{
- va_list args;
-
- if (level <= debug) {
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- va_end(args);
- }
-}
-
-int qemu_spice_rect_is_empty(const QXLRect* r)
-{
- return r->top == r->bottom || r->left == r->right;
-}
-
-void qemu_spice_rect_union(QXLRect *dest, const QXLRect *r)
-{
- if (qemu_spice_rect_is_empty(r)) {
- return;
- }
-
- if (qemu_spice_rect_is_empty(dest)) {
- *dest = *r;
- return;
- }
-
- dest->top = MIN(dest->top, r->top);
- dest->left = MIN(dest->left, r->left);
- dest->bottom = MAX(dest->bottom, r->bottom);
- dest->right = MAX(dest->right, r->right);
-}
-
-QXLCookie *qxl_cookie_new(int type, uint64_t io)
-{
- QXLCookie *cookie;
-
- cookie = g_malloc0(sizeof(*cookie));
- cookie->type = type;
- cookie->io = io;
- return cookie;
-}
-
-void qemu_spice_add_memslot(SimpleSpiceDisplay *ssd, QXLDevMemSlot *memslot,
- qxl_async_io async)
-{
- trace_qemu_spice_add_memslot(ssd->qxl.id, memslot->slot_id,
- memslot->virt_start, memslot->virt_end,
- async);
-
- if (async != QXL_SYNC) {
- spice_qxl_add_memslot_async(&ssd->qxl, memslot,
- (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
- QXL_IO_MEMSLOT_ADD_ASYNC));
- } else {
- spice_qxl_add_memslot(&ssd->qxl, memslot);
- }
-}
-
-void qemu_spice_del_memslot(SimpleSpiceDisplay *ssd, uint32_t gid, uint32_t sid)
-{
- trace_qemu_spice_del_memslot(ssd->qxl.id, gid, sid);
- spice_qxl_del_memslot(&ssd->qxl, gid, sid);
-}
-
-void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
- QXLDevSurfaceCreate *surface,
- qxl_async_io async)
-{
- trace_qemu_spice_create_primary_surface(ssd->qxl.id, id, surface, async);
- if (async != QXL_SYNC) {
- spice_qxl_create_primary_surface_async(&ssd->qxl, id, surface,
- (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
- QXL_IO_CREATE_PRIMARY_ASYNC));
- } else {
- spice_qxl_create_primary_surface(&ssd->qxl, id, surface);
- }
-}
-
-void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
- uint32_t id, qxl_async_io async)
-{
- trace_qemu_spice_destroy_primary_surface(ssd->qxl.id, id, async);
- if (async != QXL_SYNC) {
- spice_qxl_destroy_primary_surface_async(&ssd->qxl, id,
- (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
- QXL_IO_DESTROY_PRIMARY_ASYNC));
- } else {
- spice_qxl_destroy_primary_surface(&ssd->qxl, id);
- }
-}
-
-void qemu_spice_wakeup(SimpleSpiceDisplay *ssd)
-{
- trace_qemu_spice_wakeup(ssd->qxl.id);
- spice_qxl_wakeup(&ssd->qxl);
-}
-
-static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd,
- QXLRect *rect)
-{
- SimpleSpiceUpdate *update;
- QXLDrawable *drawable;
- QXLImage *image;
- QXLCommand *cmd;
- int bw, bh;
- struct timespec time_space;
- pixman_image_t *dest;
-
- trace_qemu_spice_create_update(
- rect->left, rect->right,
- rect->top, rect->bottom);
-
- update = g_malloc0(sizeof(*update));
- drawable = &update->drawable;
- image = &update->image;
- cmd = &update->ext.cmd;
-
- bw = rect->right - rect->left;
- bh = rect->bottom - rect->top;
- update->bitmap = g_malloc(bw * bh * 4);
-
- drawable->bbox = *rect;
- drawable->clip.type = SPICE_CLIP_TYPE_NONE;
- drawable->effect = QXL_EFFECT_OPAQUE;
- drawable->release_info.id = (uintptr_t)(&update->ext);
- drawable->type = QXL_DRAW_COPY;
- drawable->surfaces_dest[0] = -1;
- drawable->surfaces_dest[1] = -1;
- drawable->surfaces_dest[2] = -1;
- clock_gettime(CLOCK_MONOTONIC, &time_space);
- /* time in milliseconds from epoch. */
- drawable->mm_time = time_space.tv_sec * 1000
- + time_space.tv_nsec / 1000 / 1000;
-
- drawable->u.copy.rop_descriptor = SPICE_ROPD_OP_PUT;
- drawable->u.copy.src_bitmap = (uintptr_t)image;
- drawable->u.copy.src_area.right = bw;
- drawable->u.copy.src_area.bottom = bh;
-
- QXL_SET_IMAGE_ID(image, QXL_IMAGE_GROUP_DEVICE, ssd->unique++);
- image->descriptor.type = SPICE_IMAGE_TYPE_BITMAP;
- image->bitmap.flags = QXL_BITMAP_DIRECT | QXL_BITMAP_TOP_DOWN;
- image->bitmap.stride = bw * 4;
- image->descriptor.width = image->bitmap.x = bw;
- image->descriptor.height = image->bitmap.y = bh;
- image->bitmap.data = (uintptr_t)(update->bitmap);
- image->bitmap.palette = 0;
- image->bitmap.format = SPICE_BITMAP_FMT_32BIT;
-
- dest = pixman_image_create_bits(PIXMAN_LE_x8r8g8b8, bw, bh,
- (void *)update->bitmap, bw * 4);
- pixman_image_composite(PIXMAN_OP_SRC, ssd->surface, NULL, ssd->mirror,
- rect->left, rect->top, 0, 0,
- rect->left, rect->top, bw, bh);
- pixman_image_composite(PIXMAN_OP_SRC, ssd->mirror, NULL, dest,
- rect->left, rect->top, 0, 0,
- 0, 0, bw, bh);
- pixman_image_unref(dest);
-
- cmd->type = QXL_CMD_DRAW;
- cmd->data = (uintptr_t)drawable;
-
- QTAILQ_INSERT_TAIL(&ssd->updates, update, next);
-}
-
-static void qemu_spice_create_update(SimpleSpiceDisplay *ssd)
-{
- static const int blksize = 32;
- int blocks = (surface_width(ssd->ds) + blksize - 1) / blksize;
- int dirty_top[blocks];
- int y, yoff1, yoff2, x, xoff, blk, bw;
- int bpp = surface_bytes_per_pixel(ssd->ds);
- uint8_t *guest, *mirror;
-
- if (qemu_spice_rect_is_empty(&ssd->dirty)) {
- return;
- };
-
- for (blk = 0; blk < blocks; blk++) {
- dirty_top[blk] = -1;
- }
-
- guest = surface_data(ssd->ds);
- mirror = (void *)pixman_image_get_data(ssd->mirror);
- for (y = ssd->dirty.top; y < ssd->dirty.bottom; y++) {
- yoff1 = y * surface_stride(ssd->ds);
- yoff2 = y * pixman_image_get_stride(ssd->mirror);
- for (x = ssd->dirty.left; x < ssd->dirty.right; x += blksize) {
- xoff = x * bpp;
- blk = x / blksize;
- bw = MIN(blksize, ssd->dirty.right - x);
- if (memcmp(guest + yoff1 + xoff,
- mirror + yoff2 + xoff,
- bw * bpp) == 0) {
- if (dirty_top[blk] != -1) {
- QXLRect update = {
- .top = dirty_top[blk],
- .bottom = y,
- .left = x,
- .right = x + bw,
- };
- qemu_spice_create_one_update(ssd, &update);
- dirty_top[blk] = -1;
- }
- } else {
- if (dirty_top[blk] == -1) {
- dirty_top[blk] = y;
- }
- }
- }
- }
-
- for (x = ssd->dirty.left; x < ssd->dirty.right; x += blksize) {
- blk = x / blksize;
- bw = MIN(blksize, ssd->dirty.right - x);
- if (dirty_top[blk] != -1) {
- QXLRect update = {
- .top = dirty_top[blk],
- .bottom = ssd->dirty.bottom,
- .left = x,
- .right = x + bw,
- };
- qemu_spice_create_one_update(ssd, &update);
- dirty_top[blk] = -1;
- }
- }
-
- memset(&ssd->dirty, 0, sizeof(ssd->dirty));
-}
-
-static SimpleSpiceCursor*
-qemu_spice_create_cursor_update(SimpleSpiceDisplay *ssd,
- QEMUCursor *c,
- int on)
-{
- size_t size = c ? c->width * c->height * 4 : 0;
- SimpleSpiceCursor *update;
- QXLCursorCmd *ccmd;
- QXLCursor *cursor;
- QXLCommand *cmd;
-
- update = g_malloc0(sizeof(*update) + size);
- ccmd = &update->cmd;
- cursor = &update->cursor;
- cmd = &update->ext.cmd;
-
- if (c) {
- ccmd->type = QXL_CURSOR_SET;
- ccmd->u.set.position.x = ssd->ptr_x + ssd->hot_x;
- ccmd->u.set.position.y = ssd->ptr_y + ssd->hot_y;
- ccmd->u.set.visible = true;
- ccmd->u.set.shape = (uintptr_t)cursor;
- cursor->header.unique = ssd->unique++;
- cursor->header.type = SPICE_CURSOR_TYPE_ALPHA;
- cursor->header.width = c->width;
- cursor->header.height = c->height;
- cursor->header.hot_spot_x = c->hot_x;
- cursor->header.hot_spot_y = c->hot_y;
- cursor->data_size = size;
- cursor->chunk.data_size = size;
- memcpy(cursor->chunk.data, c->data, size);
- } else if (!on) {
- ccmd->type = QXL_CURSOR_HIDE;
- } else {
- ccmd->type = QXL_CURSOR_MOVE;
- ccmd->u.position.x = ssd->ptr_x + ssd->hot_x;
- ccmd->u.position.y = ssd->ptr_y + ssd->hot_y;
- }
- ccmd->release_info.id = (uintptr_t)(&update->ext);
-
- cmd->type = QXL_CMD_CURSOR;
- cmd->data = (uintptr_t)ccmd;
-
- return update;
-}
-
-/*
- * Called from spice server thread context (via interface_release_resource)
- * We do *not* hold the global qemu mutex here, so extra care is needed
- * when calling qemu functions. QEMU interfaces used:
- * - g_free (underlying glibc free is re-entrant).
- */
-void qemu_spice_destroy_update(SimpleSpiceDisplay *sdpy, SimpleSpiceUpdate *update)
-{
- g_free(update->bitmap);
- g_free(update);
-}
-
-void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd)
-{
- QXLDevMemSlot memslot;
-
- dprint(1, "%s/%d:\n", __func__, ssd->qxl.id);
-
- memset(&memslot, 0, sizeof(memslot));
- memslot.slot_group_id = MEMSLOT_GROUP_HOST;
- memslot.virt_end = ~0;
- qemu_spice_add_memslot(ssd, &memslot, QXL_SYNC);
-}
-
-void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
-{
- QXLDevSurfaceCreate surface;
- uint64_t surface_size;
-
- memset(&surface, 0, sizeof(surface));
-
- surface_size = (uint64_t) surface_width(ssd->ds) *
- surface_height(ssd->ds) * 4;
- assert(surface_size > 0);
- assert(surface_size < INT_MAX);
- if (ssd->bufsize < surface_size) {
- ssd->bufsize = surface_size;
- g_free(ssd->buf);
- ssd->buf = g_malloc(ssd->bufsize);
- }
-
- dprint(1, "%s/%d: %ux%u (size %" PRIu64 "/%d)\n", __func__, ssd->qxl.id,
- surface_width(ssd->ds), surface_height(ssd->ds),
- surface_size, ssd->bufsize);
-
- surface.format = SPICE_SURFACE_FMT_32_xRGB;
- surface.width = surface_width(ssd->ds);
- surface.height = surface_height(ssd->ds);
- surface.stride = -surface.width * 4;
- surface.mouse_mode = true;
- surface.flags = 0;
- surface.type = 0;
- surface.mem = (uintptr_t)ssd->buf;
- surface.group_id = MEMSLOT_GROUP_HOST;
-
- qemu_spice_create_primary_surface(ssd, 0, &surface, QXL_SYNC);
-}
-
-void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
-{
- dprint(1, "%s/%d:\n", __func__, ssd->qxl.id);
-
- qemu_spice_destroy_primary_surface(ssd, 0, QXL_SYNC);
-}
-
-void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd)
-{
- qemu_mutex_init(&ssd->lock);
- QTAILQ_INIT(&ssd->updates);
- ssd->mouse_x = -1;
- ssd->mouse_y = -1;
- if (ssd->num_surfaces == 0) {
- ssd->num_surfaces = 1024;
- }
-}
-
-/* display listener callbacks */
-
-void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
- int x, int y, int w, int h)
-{
- QXLRect update_area;
-
- dprint(2, "%s/%d: x %d y %d w %d h %d\n", __func__,
- ssd->qxl.id, x, y, w, h);
- update_area.left = x,
- update_area.right = x + w;
- update_area.top = y;
- update_area.bottom = y + h;
-
- if (qemu_spice_rect_is_empty(&ssd->dirty)) {
- ssd->notify++;
- }
- qemu_spice_rect_union(&ssd->dirty, &update_area);
-}
-
-void qemu_spice_display_switch(SimpleSpiceDisplay *ssd,
- DisplaySurface *surface)
-{
- SimpleSpiceUpdate *update;
- bool need_destroy;
-
- if (surface && ssd->surface &&
- surface_width(surface) == pixman_image_get_width(ssd->surface) &&
- surface_height(surface) == pixman_image_get_height(ssd->surface) &&
- surface_format(surface) == pixman_image_get_format(ssd->surface)) {
- /* no-resize fast path: just swap backing store */
- dprint(1, "%s/%d: fast (%dx%d)\n", __func__, ssd->qxl.id,
- surface_width(surface), surface_height(surface));
- qemu_mutex_lock(&ssd->lock);
- ssd->ds = surface;
- pixman_image_unref(ssd->surface);
- ssd->surface = pixman_image_ref(ssd->ds->image);
- qemu_mutex_unlock(&ssd->lock);
- qemu_spice_display_update(ssd, 0, 0,
- surface_width(surface),
- surface_height(surface));
- return;
- }
-
- /* full mode switch */
- dprint(1, "%s/%d: full (%dx%d -> %dx%d)\n", __func__, ssd->qxl.id,
- ssd->surface ? pixman_image_get_width(ssd->surface) : 0,
- ssd->surface ? pixman_image_get_height(ssd->surface) : 0,
- surface ? surface_width(surface) : 0,
- surface ? surface_height(surface) : 0);
-
- memset(&ssd->dirty, 0, sizeof(ssd->dirty));
- if (ssd->surface) {
- pixman_image_unref(ssd->surface);
- ssd->surface = NULL;
- pixman_image_unref(ssd->mirror);
- ssd->mirror = NULL;
- }
-
- qemu_mutex_lock(&ssd->lock);
- need_destroy = (ssd->ds != NULL);
- ssd->ds = surface;
- while ((update = QTAILQ_FIRST(&ssd->updates)) != NULL) {
- QTAILQ_REMOVE(&ssd->updates, update, next);
- qemu_spice_destroy_update(ssd, update);
- }
- qemu_mutex_unlock(&ssd->lock);
- if (need_destroy) {
- qemu_spice_destroy_host_primary(ssd);
- }
- if (ssd->ds) {
- ssd->surface = pixman_image_ref(ssd->ds->image);
- ssd->mirror = qemu_pixman_mirror_create(ssd->ds->format,
- ssd->ds->image);
- qemu_spice_create_host_primary(ssd);
- }
-
- memset(&ssd->dirty, 0, sizeof(ssd->dirty));
- ssd->notify++;
-
- qemu_mutex_lock(&ssd->lock);
- if (ssd->cursor) {
- g_free(ssd->ptr_define);
- ssd->ptr_define = qemu_spice_create_cursor_update(ssd, ssd->cursor, 0);
- }
- qemu_mutex_unlock(&ssd->lock);
-}
-
-static void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd)
-{
- if (ssd->cursor) {
- assert(ssd->dcl.con);
- dpy_cursor_define(ssd->dcl.con, ssd->cursor);
- }
- if (ssd->mouse_x != -1 && ssd->mouse_y != -1) {
- assert(ssd->dcl.con);
- dpy_mouse_set(ssd->dcl.con, ssd->mouse_x, ssd->mouse_y, 1);
- ssd->mouse_x = -1;
- ssd->mouse_y = -1;
- }
-}
-
-void qemu_spice_cursor_refresh_bh(void *opaque)
-{
- SimpleSpiceDisplay *ssd = opaque;
-
- qemu_mutex_lock(&ssd->lock);
- qemu_spice_cursor_refresh_unlocked(ssd);
- qemu_mutex_unlock(&ssd->lock);
-}
-
-void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
-{
- dprint(3, "%s/%d:\n", __func__, ssd->qxl.id);
- graphic_hw_update(ssd->dcl.con);
-
- qemu_mutex_lock(&ssd->lock);
- if (QTAILQ_EMPTY(&ssd->updates) && ssd->ds) {
- qemu_spice_create_update(ssd);
- ssd->notify++;
- }
- qemu_mutex_unlock(&ssd->lock);
-
- if (ssd->notify) {
- ssd->notify = 0;
- qemu_spice_wakeup(ssd);
- dprint(2, "%s/%d: notify\n", __func__, ssd->qxl.id);
- }
-}
-
-/* spice display interface callbacks */
-
-static void interface_attach_worker(QXLInstance *sin, QXLWorker *qxl_worker)
-{
- SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
-
- dprint(1, "%s/%d:\n", __func__, ssd->qxl.id);
- ssd->worker = qxl_worker;
-}
-
-static void interface_set_compression_level(QXLInstance *sin, int level)
-{
- dprint(1, "%s/%d:\n", __func__, sin->id);
- /* nothing to do */
-}
-
-static void interface_set_mm_time(QXLInstance *sin, uint32_t mm_time)
-{
- dprint(3, "%s/%d:\n", __func__, sin->id);
- /* nothing to do */
-}
-
-static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
-{
- SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
-
- info->memslot_gen_bits = MEMSLOT_GENERATION_BITS;
- info->memslot_id_bits = MEMSLOT_SLOT_BITS;
- info->num_memslots = NUM_MEMSLOTS;
- info->num_memslots_groups = NUM_MEMSLOTS_GROUPS;
- info->internal_groupslot_id = 0;
- info->qxl_ram_size = 16 * 1024 * 1024;
- info->n_surfaces = ssd->num_surfaces;
-}
-
-static int interface_get_command(QXLInstance *sin, QXLCommandExt *ext)
-{
- SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
- SimpleSpiceUpdate *update;
- int ret = false;
-
- dprint(3, "%s/%d:\n", __func__, ssd->qxl.id);
-
- qemu_mutex_lock(&ssd->lock);
- update = QTAILQ_FIRST(&ssd->updates);
- if (update != NULL) {
- QTAILQ_REMOVE(&ssd->updates, update, next);
- *ext = update->ext;
- ret = true;
- }
- qemu_mutex_unlock(&ssd->lock);
-
- return ret;
-}
-
-static int interface_req_cmd_notification(QXLInstance *sin)
-{
- dprint(2, "%s/%d:\n", __func__, sin->id);
- return 1;
-}
-
-static void interface_release_resource(QXLInstance *sin,
- QXLReleaseInfoExt rext)
-{
- SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
- SimpleSpiceUpdate *update;
- SimpleSpiceCursor *cursor;
- QXLCommandExt *ext;
-
- dprint(2, "%s/%d:\n", __func__, ssd->qxl.id);
- ext = (void *)(intptr_t)(rext.info->id);
- switch (ext->cmd.type) {
- case QXL_CMD_DRAW:
- update = container_of(ext, SimpleSpiceUpdate, ext);
- qemu_spice_destroy_update(ssd, update);
- break;
- case QXL_CMD_CURSOR:
- cursor = container_of(ext, SimpleSpiceCursor, ext);
- g_free(cursor);
- break;
- default:
- g_assert_not_reached();
- }
-}
-
-static int interface_get_cursor_command(QXLInstance *sin, QXLCommandExt *ext)
-{
- SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
- int ret;
-
- dprint(3, "%s/%d:\n", __func__, ssd->qxl.id);
-
- qemu_mutex_lock(&ssd->lock);
- if (ssd->ptr_define) {
- *ext = ssd->ptr_define->ext;
- ssd->ptr_define = NULL;
- ret = true;
- } else if (ssd->ptr_move) {
- *ext = ssd->ptr_move->ext;
- ssd->ptr_move = NULL;
- ret = true;
- } else {
- ret = false;
- }
- qemu_mutex_unlock(&ssd->lock);
- return ret;
-}
-
-static int interface_req_cursor_notification(QXLInstance *sin)
-{
- dprint(2, "%s:\n", __func__);
- return 1;
-}
-
-static void interface_notify_update(QXLInstance *sin, uint32_t update_id)
-{
- fprintf(stderr, "%s: abort()\n", __FUNCTION__);
- abort();
-}
-
-static int interface_flush_resources(QXLInstance *sin)
-{
- fprintf(stderr, "%s: abort()\n", __FUNCTION__);
- abort();
- return 0;
-}
-
-static void interface_update_area_complete(QXLInstance *sin,
- uint32_t surface_id,
- QXLRect *dirty, uint32_t num_updated_rects)
-{
- /* should never be called, used in qxl native mode only */
- fprintf(stderr, "%s: abort()\n", __func__);
- abort();
-}
-
-/* called from spice server thread context only */
-static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token)
-{
- QXLCookie *cookie = (QXLCookie *)(uintptr_t)cookie_token;
-
- switch (cookie->type) {
-#ifdef HAVE_SPICE_GL
- case QXL_COOKIE_TYPE_GL_DRAW_DONE:
- {
- SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
- qemu_bh_schedule(ssd->gl_unblock_bh);
- break;
- }
-#endif
- default:
- /* should never be called, used in qxl native mode only */
- fprintf(stderr, "%s: abort()\n", __func__);
- abort();
- }
- g_free(cookie);
-}
-
-static void interface_set_client_capabilities(QXLInstance *sin,
- uint8_t client_present,
- uint8_t caps[58])
-{
- dprint(3, "%s:\n", __func__);
-}
-
-static int interface_client_monitors_config(QXLInstance *sin,
- VDAgentMonitorsConfig *mc)
-{
- SimpleSpiceDisplay *ssd = container_of(sin, SimpleSpiceDisplay, qxl);
- QemuUIInfo info;
-
- if (!dpy_ui_info_supported(ssd->dcl.con)) {
- return 0; /* == not supported by guest */
- }
-
- if (!mc) {
- return 1;
- }
-
- /*
- * FIXME: multihead is tricky due to the way
- * spice has multihead implemented.
- */
- memset(&info, 0, sizeof(info));
- if (mc->num_of_monitors > 0) {
- info.width = mc->monitors[0].width;
- info.height = mc->monitors[0].height;
- }
- dpy_set_ui_info(ssd->dcl.con, &info);
- dprint(1, "%s/%d: size %dx%d\n", __func__, ssd->qxl.id,
- info.width, info.height);
- return 1;
-}
-
-static const QXLInterface dpy_interface = {
- .base.type = SPICE_INTERFACE_QXL,
- .base.description = "qemu simple display",
- .base.major_version = SPICE_INTERFACE_QXL_MAJOR,
- .base.minor_version = SPICE_INTERFACE_QXL_MINOR,
-
- .attache_worker = interface_attach_worker,
- .set_compression_level = interface_set_compression_level,
- .set_mm_time = interface_set_mm_time,
- .get_init_info = interface_get_init_info,
-
- /* the callbacks below are called from spice server thread context */
- .get_command = interface_get_command,
- .req_cmd_notification = interface_req_cmd_notification,
- .release_resource = interface_release_resource,
- .get_cursor_command = interface_get_cursor_command,
- .req_cursor_notification = interface_req_cursor_notification,
- .notify_update = interface_notify_update,
- .flush_resources = interface_flush_resources,
- .async_complete = interface_async_complete,
- .update_area_complete = interface_update_area_complete,
- .set_client_capabilities = interface_set_client_capabilities,
- .client_monitors_config = interface_client_monitors_config,
-};
-
-static void display_update(DisplayChangeListener *dcl,
- int x, int y, int w, int h)
-{
- SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
- qemu_spice_display_update(ssd, x, y, w, h);
-}
-
-static void display_switch(DisplayChangeListener *dcl,
- DisplaySurface *surface)
-{
- SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
- qemu_spice_display_switch(ssd, surface);
-}
-
-static void display_refresh(DisplayChangeListener *dcl)
-{
- SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
- qemu_spice_display_refresh(ssd);
-}
-
-static void display_mouse_set(DisplayChangeListener *dcl,
- int x, int y, int on)
-{
- SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
-
- qemu_mutex_lock(&ssd->lock);
- ssd->ptr_x = x;
- ssd->ptr_y = y;
- g_free(ssd->ptr_move);
- ssd->ptr_move = qemu_spice_create_cursor_update(ssd, NULL, on);
- qemu_mutex_unlock(&ssd->lock);
-}
-
-static void display_mouse_define(DisplayChangeListener *dcl,
- QEMUCursor *c)
-{
- SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
-
- qemu_mutex_lock(&ssd->lock);
- if (c) {
- cursor_get(c);
- }
- cursor_put(ssd->cursor);
- ssd->cursor = c;
- ssd->hot_x = c->hot_x;
- ssd->hot_y = c->hot_y;
- g_free(ssd->ptr_move);
- ssd->ptr_move = NULL;
- g_free(ssd->ptr_define);
- ssd->ptr_define = qemu_spice_create_cursor_update(ssd, c, 0);
- qemu_mutex_unlock(&ssd->lock);
-}
-
-static const DisplayChangeListenerOps display_listener_ops = {
- .dpy_name = "spice",
- .dpy_gfx_update = display_update,
- .dpy_gfx_switch = display_switch,
- .dpy_gfx_check_format = qemu_pixman_check_format,
- .dpy_refresh = display_refresh,
- .dpy_mouse_set = display_mouse_set,
- .dpy_cursor_define = display_mouse_define,
-};
-
-#ifdef HAVE_SPICE_GL
-
-static void qemu_spice_gl_block(SimpleSpiceDisplay *ssd, bool block)
-{
- uint64_t timeout;
-
- if (block) {
- timeout = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
- timeout += 1000; /* one sec */
- timer_mod(ssd->gl_unblock_timer, timeout);
- } else {
- timer_del(ssd->gl_unblock_timer);
- }
- graphic_hw_gl_block(ssd->dcl.con, block);
-}
-
-static void qemu_spice_gl_unblock_bh(void *opaque)
-{
- SimpleSpiceDisplay *ssd = opaque;
-
- qemu_spice_gl_block(ssd, false);
-}
-
-static void qemu_spice_gl_block_timer(void *opaque)
-{
- fprintf(stderr, "WARNING: spice: no gl-draw-done within one second\n");
-}
-
-static QEMUGLContext qemu_spice_gl_create_context(DisplayChangeListener *dcl,
- QEMUGLParams *params)
-{
- eglMakeCurrent(qemu_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
- qemu_egl_rn_ctx);
- return qemu_egl_create_context(dcl, params);
-}
-
-static void qemu_spice_gl_scanout(DisplayChangeListener *dcl,
- uint32_t tex_id,
- bool y_0_top,
- uint32_t x, uint32_t y,
- uint32_t w, uint32_t h)
-{
- SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
- EGLint stride = 0, fourcc = 0;
- int fd = -1;
-
- if (tex_id) {
- fd = egl_get_fd_for_texture(tex_id, &stride, &fourcc);
- if (fd < 0) {
- fprintf(stderr, "%s: failed to get fd for texture\n", __func__);
- return;
- }
- dprint(1, "%s: %dx%d (stride %d, fourcc 0x%x)\n", __func__,
- w, h, stride, fourcc);
- } else {
- dprint(1, "%s: no texture (no framebuffer)\n", __func__);
- }
-
- assert(!tex_id || fd >= 0);
-
- /* note: spice server will close the fd */
- spice_qxl_gl_scanout(&ssd->qxl, fd,
- surface_width(ssd->ds),
- surface_height(ssd->ds),
- stride, fourcc, y_0_top);
-}
-
-static void qemu_spice_gl_update(DisplayChangeListener *dcl,
- uint32_t x, uint32_t y, uint32_t w, uint32_t h)
-{
- SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl);
- uint64_t cookie;
-
- dprint(2, "%s: %dx%d+%d+%d\n", __func__, w, h, x, y);
- qemu_spice_gl_block(ssd, true);
- cookie = (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_GL_DRAW_DONE, 0);
- spice_qxl_gl_draw_async(&ssd->qxl, x, y, w, h, cookie);
-}
-
-static const DisplayChangeListenerOps display_listener_gl_ops = {
- .dpy_name = "spice-egl",
- .dpy_gfx_update = display_update,
- .dpy_gfx_switch = display_switch,
- .dpy_gfx_check_format = qemu_pixman_check_format,
- .dpy_refresh = display_refresh,
- .dpy_mouse_set = display_mouse_set,
- .dpy_cursor_define = display_mouse_define,
-
- .dpy_gl_ctx_create = qemu_spice_gl_create_context,
- .dpy_gl_ctx_destroy = qemu_egl_destroy_context,
- .dpy_gl_ctx_make_current = qemu_egl_make_context_current,
- .dpy_gl_ctx_get_current = qemu_egl_get_current_context,
-
- .dpy_gl_scanout = qemu_spice_gl_scanout,
- .dpy_gl_update = qemu_spice_gl_update,
-};
-
-#endif /* HAVE_SPICE_GL */
-
-static void qemu_spice_display_init_one(QemuConsole *con)
-{
- SimpleSpiceDisplay *ssd = g_new0(SimpleSpiceDisplay, 1);
-
- qemu_spice_display_init_common(ssd);
-
- ssd->dcl.ops = &display_listener_ops;
-#ifdef HAVE_SPICE_GL
- if (display_opengl) {
- ssd->dcl.ops = &display_listener_gl_ops;
- ssd->dmabuf_fd = -1;
- ssd->gl_unblock_bh = qemu_bh_new(qemu_spice_gl_unblock_bh, ssd);
- ssd->gl_unblock_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
- qemu_spice_gl_block_timer, ssd);
- }
-#endif
- ssd->dcl.con = con;
-
- ssd->qxl.base.sif = &dpy_interface.base;
- qemu_spice_add_display_interface(&ssd->qxl, con);
- assert(ssd->worker);
- qemu_spice_create_host_memslot(ssd);
-
- register_displaychangelistener(&ssd->dcl);
-}
-
-void qemu_spice_display_init(void)
-{
- QemuConsole *con;
- int i;
-
- for (i = 0;; i++) {
- con = qemu_console_lookup_by_index(i);
- if (!con || !qemu_console_is_graphic(con)) {
- break;
- }
- if (qemu_spice_have_display_interface(con)) {
- continue;
- }
- qemu_spice_display_init_one(con);
- }
-}
diff --git a/qemu/ui/spice-input.c b/qemu/ui/spice-input.c
deleted file mode 100644
index 8eeebdbb2..000000000
--- a/qemu/ui/spice-input.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (C) 2010 Red Hat, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-
-#include <spice.h>
-#include <spice/enums.h>
-
-#include "qemu-common.h"
-#include "ui/qemu-spice.h"
-#include "ui/console.h"
-#include "ui/keymaps.h"
-#include "ui/input.h"
-
-/* keyboard bits */
-
-typedef struct QemuSpiceKbd {
- SpiceKbdInstance sin;
- int ledstate;
- bool emul0;
-} QemuSpiceKbd;
-
-static void kbd_push_key(SpiceKbdInstance *sin, uint8_t frag);
-static uint8_t kbd_get_leds(SpiceKbdInstance *sin);
-static void kbd_leds(void *opaque, int l);
-
-static const SpiceKbdInterface kbd_interface = {
- .base.type = SPICE_INTERFACE_KEYBOARD,
- .base.description = "qemu keyboard",
- .base.major_version = SPICE_INTERFACE_KEYBOARD_MAJOR,
- .base.minor_version = SPICE_INTERFACE_KEYBOARD_MINOR,
- .push_scan_freg = kbd_push_key,
- .get_leds = kbd_get_leds,
-};
-
-static void kbd_push_key(SpiceKbdInstance *sin, uint8_t scancode)
-{
- QemuSpiceKbd *kbd = container_of(sin, QemuSpiceKbd, sin);
- int keycode;
- bool up;
-
- if (scancode == SCANCODE_EMUL0) {
- kbd->emul0 = true;
- return;
- }
- keycode = scancode & ~SCANCODE_UP;
- up = scancode & SCANCODE_UP;
- if (kbd->emul0) {
- kbd->emul0 = false;
- keycode |= SCANCODE_GREY;
- }
-
- qemu_input_event_send_key_number(NULL, keycode, !up);
-}
-
-static uint8_t kbd_get_leds(SpiceKbdInstance *sin)
-{
- QemuSpiceKbd *kbd = container_of(sin, QemuSpiceKbd, sin);
- return kbd->ledstate;
-}
-
-static void kbd_leds(void *opaque, int ledstate)
-{
- QemuSpiceKbd *kbd = opaque;
-
- kbd->ledstate = 0;
- if (ledstate & QEMU_SCROLL_LOCK_LED) {
- kbd->ledstate |= SPICE_KEYBOARD_MODIFIER_FLAGS_SCROLL_LOCK;
- }
- if (ledstate & QEMU_NUM_LOCK_LED) {
- kbd->ledstate |= SPICE_KEYBOARD_MODIFIER_FLAGS_NUM_LOCK;
- }
- if (ledstate & QEMU_CAPS_LOCK_LED) {
- kbd->ledstate |= SPICE_KEYBOARD_MODIFIER_FLAGS_CAPS_LOCK;
- }
- spice_server_kbd_leds(&kbd->sin, ledstate);
-}
-
-/* mouse bits */
-
-typedef struct QemuSpicePointer {
- SpiceMouseInstance mouse;
- SpiceTabletInstance tablet;
- int width, height;
- uint32_t last_bmask;
- Notifier mouse_mode;
- bool absolute;
-} QemuSpicePointer;
-
-static void spice_update_buttons(QemuSpicePointer *pointer,
- int wheel, uint32_t button_mask)
-{
- static uint32_t bmap[INPUT_BUTTON__MAX] = {
- [INPUT_BUTTON_LEFT] = 0x01,
- [INPUT_BUTTON_MIDDLE] = 0x04,
- [INPUT_BUTTON_RIGHT] = 0x02,
- [INPUT_BUTTON_WHEEL_UP] = 0x10,
- [INPUT_BUTTON_WHEEL_DOWN] = 0x20,
- };
-
- if (wheel < 0) {
- button_mask |= 0x10;
- }
- if (wheel > 0) {
- button_mask |= 0x20;
- }
-
- if (pointer->last_bmask == button_mask) {
- return;
- }
- qemu_input_update_buttons(NULL, bmap, pointer->last_bmask, button_mask);
- pointer->last_bmask = button_mask;
-}
-
-static void mouse_motion(SpiceMouseInstance *sin, int dx, int dy, int dz,
- uint32_t buttons_state)
-{
- QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, mouse);
- spice_update_buttons(pointer, dz, buttons_state);
- qemu_input_queue_rel(NULL, INPUT_AXIS_X, dx);
- qemu_input_queue_rel(NULL, INPUT_AXIS_Y, dy);
- qemu_input_event_sync();
-}
-
-static void mouse_buttons(SpiceMouseInstance *sin, uint32_t buttons_state)
-{
- QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, mouse);
- spice_update_buttons(pointer, 0, buttons_state);
- qemu_input_event_sync();
-}
-
-static const SpiceMouseInterface mouse_interface = {
- .base.type = SPICE_INTERFACE_MOUSE,
- .base.description = "mouse",
- .base.major_version = SPICE_INTERFACE_MOUSE_MAJOR,
- .base.minor_version = SPICE_INTERFACE_MOUSE_MINOR,
- .motion = mouse_motion,
- .buttons = mouse_buttons,
-};
-
-static void tablet_set_logical_size(SpiceTabletInstance* sin, int width, int height)
-{
- QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet);
-
- if (height < 16) {
- height = 16;
- }
- if (width < 16) {
- width = 16;
- }
- pointer->width = width;
- pointer->height = height;
-}
-
-static void tablet_position(SpiceTabletInstance* sin, int x, int y,
- uint32_t buttons_state)
-{
- QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet);
-
- spice_update_buttons(pointer, 0, buttons_state);
- qemu_input_queue_abs(NULL, INPUT_AXIS_X, x, pointer->width);
- qemu_input_queue_abs(NULL, INPUT_AXIS_Y, y, pointer->height);
- qemu_input_event_sync();
-}
-
-
-static void tablet_wheel(SpiceTabletInstance* sin, int wheel,
- uint32_t buttons_state)
-{
- QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet);
-
- spice_update_buttons(pointer, wheel, buttons_state);
- qemu_input_event_sync();
-}
-
-static void tablet_buttons(SpiceTabletInstance *sin,
- uint32_t buttons_state)
-{
- QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet);
-
- spice_update_buttons(pointer, 0, buttons_state);
- qemu_input_event_sync();
-}
-
-static const SpiceTabletInterface tablet_interface = {
- .base.type = SPICE_INTERFACE_TABLET,
- .base.description = "tablet",
- .base.major_version = SPICE_INTERFACE_TABLET_MAJOR,
- .base.minor_version = SPICE_INTERFACE_TABLET_MINOR,
- .set_logical_size = tablet_set_logical_size,
- .position = tablet_position,
- .wheel = tablet_wheel,
- .buttons = tablet_buttons,
-};
-
-static void mouse_mode_notifier(Notifier *notifier, void *data)
-{
- QemuSpicePointer *pointer = container_of(notifier, QemuSpicePointer, mouse_mode);
- bool is_absolute = qemu_input_is_absolute();
-
- if (pointer->absolute == is_absolute) {
- return;
- }
-
- if (is_absolute) {
- qemu_spice_add_interface(&pointer->tablet.base);
- } else {
- spice_server_remove_interface(&pointer->tablet.base);
- }
- pointer->absolute = is_absolute;
-}
-
-void qemu_spice_input_init(void)
-{
- QemuSpiceKbd *kbd;
- QemuSpicePointer *pointer;
-
- kbd = g_malloc0(sizeof(*kbd));
- kbd->sin.base.sif = &kbd_interface.base;
- qemu_spice_add_interface(&kbd->sin.base);
- qemu_add_led_event_handler(kbd_leds, kbd);
-
- pointer = g_malloc0(sizeof(*pointer));
- pointer->mouse.base.sif = &mouse_interface.base;
- pointer->tablet.base.sif = &tablet_interface.base;
- qemu_spice_add_interface(&pointer->mouse.base);
-
- pointer->absolute = false;
- pointer->mouse_mode.notify = mouse_mode_notifier;
- qemu_add_mouse_mode_change_notifier(&pointer->mouse_mode);
- mouse_mode_notifier(&pointer->mouse_mode, NULL);
-}
diff --git a/qemu/ui/vgafont.h b/qemu/ui/vgafont.h
deleted file mode 100644
index 3606dd733..000000000
--- a/qemu/ui/vgafont.h
+++ /dev/null
@@ -1,4611 +0,0 @@
-static const uint8_t vgafont16[256 * 16] = {
-
- /* 0 0x00 '^@' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 1 0x01 '^A' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x81, /* 10000001 */
- 0xa5, /* 10100101 */
- 0x81, /* 10000001 */
- 0x81, /* 10000001 */
- 0xbd, /* 10111101 */
- 0x99, /* 10011001 */
- 0x81, /* 10000001 */
- 0x81, /* 10000001 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 2 0x02 '^B' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0xff, /* 11111111 */
- 0xdb, /* 11011011 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xc3, /* 11000011 */
- 0xe7, /* 11100111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 3 0x03 '^C' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x6c, /* 01101100 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0x7c, /* 01111100 */
- 0x38, /* 00111000 */
- 0x10, /* 00010000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 4 0x04 '^D' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x7c, /* 01111100 */
- 0xfe, /* 11111110 */
- 0x7c, /* 01111100 */
- 0x38, /* 00111000 */
- 0x10, /* 00010000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 5 0x05 '^E' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0xe7, /* 11100111 */
- 0xe7, /* 11100111 */
- 0xe7, /* 11100111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 6 0x06 '^F' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x7e, /* 01111110 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 7 0x07 '^G' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 8 0x08 '^H' */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xe7, /* 11100111 */
- 0xc3, /* 11000011 */
- 0xc3, /* 11000011 */
- 0xe7, /* 11100111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
-
- /* 9 0x09 '^I' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x42, /* 01000010 */
- 0x42, /* 01000010 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 10 0x0a '^J' */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xc3, /* 11000011 */
- 0x99, /* 10011001 */
- 0xbd, /* 10111101 */
- 0xbd, /* 10111101 */
- 0x99, /* 10011001 */
- 0xc3, /* 11000011 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
-
- /* 11 0x0b '^K' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1e, /* 00011110 */
- 0x0e, /* 00001110 */
- 0x1a, /* 00011010 */
- 0x32, /* 00110010 */
- 0x78, /* 01111000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 12 0x0c '^L' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 13 0x0d '^M' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3f, /* 00111111 */
- 0x33, /* 00110011 */
- 0x3f, /* 00111111 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x70, /* 01110000 */
- 0xf0, /* 11110000 */
- 0xe0, /* 11100000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 14 0x0e '^N' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7f, /* 01111111 */
- 0x63, /* 01100011 */
- 0x7f, /* 01111111 */
- 0x63, /* 01100011 */
- 0x63, /* 01100011 */
- 0x63, /* 01100011 */
- 0x63, /* 01100011 */
- 0x67, /* 01100111 */
- 0xe7, /* 11100111 */
- 0xe6, /* 11100110 */
- 0xc0, /* 11000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 15 0x0f '^O' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xdb, /* 11011011 */
- 0x3c, /* 00111100 */
- 0xe7, /* 11100111 */
- 0x3c, /* 00111100 */
- 0xdb, /* 11011011 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 16 0x10 '^P' */
- 0x00, /* 00000000 */
- 0x80, /* 10000000 */
- 0xc0, /* 11000000 */
- 0xe0, /* 11100000 */
- 0xf0, /* 11110000 */
- 0xf8, /* 11111000 */
- 0xfe, /* 11111110 */
- 0xf8, /* 11111000 */
- 0xf0, /* 11110000 */
- 0xe0, /* 11100000 */
- 0xc0, /* 11000000 */
- 0x80, /* 10000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 17 0x11 '^Q' */
- 0x00, /* 00000000 */
- 0x02, /* 00000010 */
- 0x06, /* 00000110 */
- 0x0e, /* 00001110 */
- 0x1e, /* 00011110 */
- 0x3e, /* 00111110 */
- 0xfe, /* 11111110 */
- 0x3e, /* 00111110 */
- 0x1e, /* 00011110 */
- 0x0e, /* 00001110 */
- 0x06, /* 00000110 */
- 0x02, /* 00000010 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 18 0x12 '^R' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 19 0x13 '^S' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 20 0x14 '^T' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7f, /* 01111111 */
- 0xdb, /* 11011011 */
- 0xdb, /* 11011011 */
- 0xdb, /* 11011011 */
- 0x7b, /* 01111011 */
- 0x1b, /* 00011011 */
- 0x1b, /* 00011011 */
- 0x1b, /* 00011011 */
- 0x1b, /* 00011011 */
- 0x1b, /* 00011011 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 21 0x15 '^U' */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0x60, /* 01100000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x0c, /* 00001100 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 22 0x16 '^V' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 23 0x17 '^W' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 24 0x18 '^X' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 25 0x19 '^Y' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 26 0x1a '^Z' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0xfe, /* 11111110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 27 0x1b '^[' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xfe, /* 11111110 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 28 0x1c '^\' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 29 0x1d '^]' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x28, /* 00101000 */
- 0x6c, /* 01101100 */
- 0xfe, /* 11111110 */
- 0x6c, /* 01101100 */
- 0x28, /* 00101000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 30 0x1e '^^' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x38, /* 00111000 */
- 0x7c, /* 01111100 */
- 0x7c, /* 01111100 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 31 0x1f '^_' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0x7c, /* 01111100 */
- 0x7c, /* 01111100 */
- 0x38, /* 00111000 */
- 0x38, /* 00111000 */
- 0x10, /* 00010000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 32 0x20 ' ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 33 0x21 '!' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 34 0x22 '"' */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x24, /* 00100100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 35 0x23 '#' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0xfe, /* 11111110 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0xfe, /* 11111110 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 36 0x24 '$' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc2, /* 11000010 */
- 0xc0, /* 11000000 */
- 0x7c, /* 01111100 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x86, /* 10000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 37 0x25 '%' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc2, /* 11000010 */
- 0xc6, /* 11000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc6, /* 11000110 */
- 0x86, /* 10000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 38 0x26 '&' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 39 0x27 ''' */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 40 0x28 '(' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 41 0x29 ')' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 42 0x2a '*' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0xff, /* 11111111 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 43 0x2b '+' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 44 0x2c ',' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 45 0x2d '-' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 46 0x2e '.' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 47 0x2f '/' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x02, /* 00000010 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0x80, /* 10000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 48 0x30 '0' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 49 0x31 '1' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x38, /* 00111000 */
- 0x78, /* 01111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 50 0x32 '2' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 51 0x33 '3' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x3c, /* 00111100 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 52 0x34 '4' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x0c, /* 00001100 */
- 0x1c, /* 00011100 */
- 0x3c, /* 00111100 */
- 0x6c, /* 01101100 */
- 0xcc, /* 11001100 */
- 0xfe, /* 11111110 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x1e, /* 00011110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 53 0x35 '5' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xfc, /* 11111100 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 54 0x36 '6' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xfc, /* 11111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 55 0x37 '7' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 56 0x38 '8' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 57 0x39 '9' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7e, /* 01111110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 58 0x3a ':' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 59 0x3b ';' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 60 0x3c '<' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x06, /* 00000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 61 0x3d '=' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 62 0x3e '>' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 63 0x3f '?' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 64 0x40 '@' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xde, /* 11011110 */
- 0xde, /* 11011110 */
- 0xde, /* 11011110 */
- 0xdc, /* 11011100 */
- 0xc0, /* 11000000 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 65 0x41 'A' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 66 0x42 'B' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfc, /* 11111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0xfc, /* 11111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 67 0x43 'C' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0xc2, /* 11000010 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc2, /* 11000010 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 68 0x44 'D' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xf8, /* 11111000 */
- 0x6c, /* 01101100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x6c, /* 01101100 */
- 0xf8, /* 11111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 69 0x45 'E' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x66, /* 01100110 */
- 0x62, /* 01100010 */
- 0x68, /* 01101000 */
- 0x78, /* 01111000 */
- 0x68, /* 01101000 */
- 0x60, /* 01100000 */
- 0x62, /* 01100010 */
- 0x66, /* 01100110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 70 0x46 'F' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x66, /* 01100110 */
- 0x62, /* 01100010 */
- 0x68, /* 01101000 */
- 0x78, /* 01111000 */
- 0x68, /* 01101000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xf0, /* 11110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 71 0x47 'G' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0xc2, /* 11000010 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xde, /* 11011110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x66, /* 01100110 */
- 0x3a, /* 00111010 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 72 0x48 'H' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 73 0x49 'I' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 74 0x4a 'J' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1e, /* 00011110 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 75 0x4b 'K' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xe6, /* 11100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x6c, /* 01101100 */
- 0x78, /* 01111000 */
- 0x78, /* 01111000 */
- 0x6c, /* 01101100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0xe6, /* 11100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 76 0x4c 'L' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xf0, /* 11110000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x62, /* 01100010 */
- 0x66, /* 01100110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 77 0x4d 'M' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xee, /* 11101110 */
- 0xfe, /* 11111110 */
- 0xfe, /* 11111110 */
- 0xd6, /* 11010110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 78 0x4e 'N' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xe6, /* 11100110 */
- 0xf6, /* 11110110 */
- 0xfe, /* 11111110 */
- 0xde, /* 11011110 */
- 0xce, /* 11001110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 79 0x4f 'O' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 80 0x50 'P' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfc, /* 11111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xf0, /* 11110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 81 0x51 'Q' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xd6, /* 11010110 */
- 0xde, /* 11011110 */
- 0x7c, /* 01111100 */
- 0x0c, /* 00001100 */
- 0x0e, /* 00001110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 82 0x52 'R' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfc, /* 11111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x6c, /* 01101100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0xe6, /* 11100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 83 0x53 'S' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x60, /* 01100000 */
- 0x38, /* 00111000 */
- 0x0c, /* 00001100 */
- 0x06, /* 00000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 84 0x54 'T' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x5a, /* 01011010 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 85 0x55 'U' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 86 0x56 'V' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x10, /* 00010000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 87 0x57 'W' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xfe, /* 11111110 */
- 0xee, /* 11101110 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 88 0x58 'X' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x7c, /* 01111100 */
- 0x38, /* 00111000 */
- 0x38, /* 00111000 */
- 0x7c, /* 01111100 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 89 0x59 'Y' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 90 0x5a 'Z' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0x86, /* 10000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc2, /* 11000010 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 91 0x5b '[' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 92 0x5c '\' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x80, /* 10000000 */
- 0xc0, /* 11000000 */
- 0xe0, /* 11100000 */
- 0x70, /* 01110000 */
- 0x38, /* 00111000 */
- 0x1c, /* 00011100 */
- 0x0e, /* 00001110 */
- 0x06, /* 00000110 */
- 0x02, /* 00000010 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 93 0x5d ']' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 94 0x5e '^' */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 95 0x5f '_' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 96 0x60 '`' */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 97 0x61 'a' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 98 0x62 'b' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xe0, /* 11100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x78, /* 01111000 */
- 0x6c, /* 01101100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 99 0x63 'c' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 100 0x64 'd' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1c, /* 00011100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x3c, /* 00111100 */
- 0x6c, /* 01101100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 101 0x65 'e' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 102 0x66 'f' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1c, /* 00011100 */
- 0x36, /* 00110110 */
- 0x32, /* 00110010 */
- 0x30, /* 00110000 */
- 0x78, /* 01111000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 103 0x67 'g' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x7c, /* 01111100 */
- 0x0c, /* 00001100 */
- 0xcc, /* 11001100 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
-
- /* 104 0x68 'h' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xe0, /* 11100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x6c, /* 01101100 */
- 0x76, /* 01110110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0xe6, /* 11100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 105 0x69 'i' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 106 0x6a 'j' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x00, /* 00000000 */
- 0x0e, /* 00001110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
-
- /* 107 0x6b 'k' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xe0, /* 11100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x66, /* 01100110 */
- 0x6c, /* 01101100 */
- 0x78, /* 01111000 */
- 0x78, /* 01111000 */
- 0x6c, /* 01101100 */
- 0x66, /* 01100110 */
- 0xe6, /* 11100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 108 0x6c 'l' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 109 0x6d 'm' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xec, /* 11101100 */
- 0xfe, /* 11111110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 110 0x6e 'n' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xdc, /* 11011100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 111 0x6f 'o' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 112 0x70 'p' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xdc, /* 11011100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xf0, /* 11110000 */
- 0x00, /* 00000000 */
-
- /* 113 0x71 'q' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x7c, /* 01111100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x1e, /* 00011110 */
- 0x00, /* 00000000 */
-
- /* 114 0x72 'r' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xdc, /* 11011100 */
- 0x76, /* 01110110 */
- 0x66, /* 01100110 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xf0, /* 11110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 115 0x73 's' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0x60, /* 01100000 */
- 0x38, /* 00111000 */
- 0x0c, /* 00001100 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 116 0x74 't' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0xfc, /* 11111100 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x36, /* 00110110 */
- 0x1c, /* 00011100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 117 0x75 'u' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 118 0x76 'v' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 119 0x77 'w' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xd6, /* 11010110 */
- 0xfe, /* 11111110 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 120 0x78 'x' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x38, /* 00111000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 121 0x79 'y' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7e, /* 01111110 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0xf8, /* 11111000 */
- 0x00, /* 00000000 */
-
- /* 122 0x7a 'z' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xcc, /* 11001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 123 0x7b '{' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x0e, /* 00001110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x70, /* 01110000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x0e, /* 00001110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 124 0x7c '|' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 125 0x7d '}' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x70, /* 01110000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x0e, /* 00001110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 126 0x7e '~' */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 127 0x7f '' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 128 0x80 '€' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0xc2, /* 11000010 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc2, /* 11000010 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 129 0x81 '' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 130 0x82 '‚' */
- 0x00, /* 00000000 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 131 0x83 'ƒ' */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 132 0x84 '„' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 133 0x85 '…' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 134 0x86 '†' */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 135 0x87 '‡' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x18, /* 00011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 136 0x88 'ˆ' */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 137 0x89 '‰' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 138 0x8a 'Š' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 139 0x8b '‹' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 140 0x8c 'Œ' */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 141 0x8d '' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 142 0x8e 'Ž' */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 143 0x8f '' */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 144 0x90 '' */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x66, /* 01100110 */
- 0x62, /* 01100010 */
- 0x68, /* 01101000 */
- 0x78, /* 01111000 */
- 0x68, /* 01101000 */
- 0x62, /* 01100010 */
- 0x66, /* 01100110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 145 0x91 '‘' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xec, /* 11101100 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x7e, /* 01111110 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0x6e, /* 01101110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 146 0x92 '’' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3e, /* 00111110 */
- 0x6c, /* 01101100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xfe, /* 11111110 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xce, /* 11001110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 147 0x93 '“' */
- 0x00, /* 00000000 */
- 0x10, /* 00010000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 148 0x94 '”' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 149 0x95 '•' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 150 0x96 '–' */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x78, /* 01111000 */
- 0xcc, /* 11001100 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 151 0x97 '—' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 152 0x98 '˜' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7e, /* 01111110 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x78, /* 01111000 */
- 0x00, /* 00000000 */
-
- /* 153 0x99 '™' */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 154 0x9a 'š' */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 155 0x9b '›' */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 156 0x9c 'œ' */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x64, /* 01100100 */
- 0x60, /* 01100000 */
- 0xf0, /* 11110000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xe6, /* 11100110 */
- 0xfc, /* 11111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 157 0x9d '' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 158 0x9e 'ž' */
- 0x00, /* 00000000 */
- 0xf8, /* 11111000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xf8, /* 11111000 */
- 0xc4, /* 11000100 */
- 0xcc, /* 11001100 */
- 0xde, /* 11011110 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 159 0x9f 'Ÿ' */
- 0x00, /* 00000000 */
- 0x0e, /* 00001110 */
- 0x1b, /* 00011011 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xd8, /* 11011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 160 0xa0 ' ' */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0x0c, /* 00001100 */
- 0x7c, /* 01111100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 161 0xa1 '¡' */
- 0x00, /* 00000000 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 162 0xa2 '¢' */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 163 0xa3 '£' */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x00, /* 00000000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 164 0xa4 '¤' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x00, /* 00000000 */
- 0xdc, /* 11011100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 165 0xa5 '¥' */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x00, /* 00000000 */
- 0xc6, /* 11000110 */
- 0xe6, /* 11100110 */
- 0xf6, /* 11110110 */
- 0xfe, /* 11111110 */
- 0xde, /* 11011110 */
- 0xce, /* 11001110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 166 0xa6 '¦' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x3e, /* 00111110 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 167 0xa7 '§' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 168 0xa8 '¨' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x7c, /* 01111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 169 0xa9 '©' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 170 0xaa 'ª' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 171 0xab '«' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0xe0, /* 11100000 */
- 0x62, /* 01100010 */
- 0x66, /* 01100110 */
- 0x6c, /* 01101100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xdc, /* 11011100 */
- 0x86, /* 10000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x3e, /* 00111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 172 0xac '¬' */
- 0x00, /* 00000000 */
- 0x60, /* 01100000 */
- 0xe0, /* 11100000 */
- 0x62, /* 01100010 */
- 0x66, /* 01100110 */
- 0x6c, /* 01101100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x66, /* 01100110 */
- 0xce, /* 11001110 */
- 0x9a, /* 10011010 */
- 0x3f, /* 00111111 */
- 0x06, /* 00000110 */
- 0x06, /* 00000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 173 0xad '­' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 174 0xae '®' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x36, /* 00110110 */
- 0x6c, /* 01101100 */
- 0xd8, /* 11011000 */
- 0x6c, /* 01101100 */
- 0x36, /* 00110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 175 0xaf '¯' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xd8, /* 11011000 */
- 0x6c, /* 01101100 */
- 0x36, /* 00110110 */
- 0x6c, /* 01101100 */
- 0xd8, /* 11011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 176 0xb0 '°' */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
- 0x11, /* 00010001 */
- 0x44, /* 01000100 */
-
- /* 177 0xb1 '±' */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
- 0x55, /* 01010101 */
- 0xaa, /* 10101010 */
-
- /* 178 0xb2 '²' */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
- 0xdd, /* 11011101 */
- 0x77, /* 01110111 */
-
- /* 179 0xb3 '³' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 180 0xb4 '´' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 181 0xb5 'µ' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 182 0xb6 '¶' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xf6, /* 11110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 183 0xb7 '·' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 184 0xb8 '¸' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 185 0xb9 '¹' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xf6, /* 11110110 */
- 0x06, /* 00000110 */
- 0xf6, /* 11110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 186 0xba 'º' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 187 0xbb '»' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x06, /* 00000110 */
- 0xf6, /* 11110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 188 0xbc '¼' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xf6, /* 11110110 */
- 0x06, /* 00000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 189 0xbd '½' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 190 0xbe '¾' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 191 0xbf '¿' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xf8, /* 11111000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 192 0xc0 'À' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 193 0xc1 'Á' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 194 0xc2 'Â' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 195 0xc3 'Ã' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 196 0xc4 'Ä' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 197 0xc5 'Å' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xff, /* 11111111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 198 0xc6 'Æ' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 199 0xc7 'Ç' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x37, /* 00110111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 200 0xc8 'È' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x37, /* 00110111 */
- 0x30, /* 00110000 */
- 0x3f, /* 00111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 201 0xc9 'É' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3f, /* 00111111 */
- 0x30, /* 00110000 */
- 0x37, /* 00110111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 202 0xca 'Ê' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xf7, /* 11110111 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 203 0xcb 'Ë' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0xf7, /* 11110111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 204 0xcc 'Ì' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x37, /* 00110111 */
- 0x30, /* 00110000 */
- 0x37, /* 00110111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 205 0xcd 'Í' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 206 0xce 'Î' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xf7, /* 11110111 */
- 0x00, /* 00000000 */
- 0xf7, /* 11110111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 207 0xcf 'Ï' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 208 0xd0 'Ð' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 209 0xd1 'Ñ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 210 0xd2 'Ò' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 211 0xd3 'Ó' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x3f, /* 00111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 212 0xd4 'Ô' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 213 0xd5 'Õ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 214 0xd6 'Ö' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x3f, /* 00111111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 215 0xd7 '×' */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0xff, /* 11111111 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
-
- /* 216 0xd8 'Ø' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xff, /* 11111111 */
- 0x18, /* 00011000 */
- 0xff, /* 11111111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 217 0xd9 'Ù' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xf8, /* 11111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 218 0xda 'Ú' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1f, /* 00011111 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 219 0xdb 'Û' */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
-
- /* 220 0xdc 'Ü' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
-
- /* 221 0xdd 'Ý' */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
- 0xf0, /* 11110000 */
-
- /* 222 0xde 'Þ' */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
- 0x0f, /* 00001111 */
-
- /* 223 0xdf 'ß' */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0xff, /* 11111111 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 224 0xe0 'à' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xdc, /* 11011100 */
- 0x76, /* 01110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 225 0xe1 'á' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x78, /* 01111000 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xcc, /* 11001100 */
- 0xd8, /* 11011000 */
- 0xcc, /* 11001100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xcc, /* 11001100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 226 0xe2 'â' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0xc0, /* 11000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 227 0xe3 'ã' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 228 0xe4 'ä' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 229 0xe5 'å' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 230 0xe6 'æ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x7c, /* 01111100 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0x00, /* 00000000 */
-
- /* 231 0xe7 'ç' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 232 0xe8 'è' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 233 0xe9 'é' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xfe, /* 11111110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 234 0xea 'ê' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0xee, /* 11101110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 235 0xeb 'ë' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1e, /* 00011110 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x3e, /* 00111110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x66, /* 01100110 */
- 0x3c, /* 00111100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 236 0xec 'ì' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0xdb, /* 11011011 */
- 0xdb, /* 11011011 */
- 0xdb, /* 11011011 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 237 0xed 'í' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x03, /* 00000011 */
- 0x06, /* 00000110 */
- 0x7e, /* 01111110 */
- 0xdb, /* 11011011 */
- 0xdb, /* 11011011 */
- 0xf3, /* 11110011 */
- 0x7e, /* 01111110 */
- 0x60, /* 01100000 */
- 0xc0, /* 11000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 238 0xee 'î' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x1c, /* 00011100 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x7c, /* 01111100 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x1c, /* 00011100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 239 0xef 'ï' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7c, /* 01111100 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0xc6, /* 11000110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 240 0xf0 'ð' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0xfe, /* 11111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 241 0xf1 'ñ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x7e, /* 01111110 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 242 0xf2 'ò' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x06, /* 00000110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 243 0xf3 'ó' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x30, /* 00110000 */
- 0x60, /* 01100000 */
- 0x30, /* 00110000 */
- 0x18, /* 00011000 */
- 0x0c, /* 00001100 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 244 0xf4 'ô' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x0e, /* 00001110 */
- 0x1b, /* 00011011 */
- 0x1b, /* 00011011 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
-
- /* 245 0xf5 'õ' */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0xd8, /* 11011000 */
- 0x70, /* 01110000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 246 0xf6 'ö' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 247 0xf7 '÷' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x00, /* 00000000 */
- 0x76, /* 01110110 */
- 0xdc, /* 11011100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 248 0xf8 'ø' */
- 0x00, /* 00000000 */
- 0x38, /* 00111000 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x38, /* 00111000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 249 0xf9 'ù' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 250 0xfa 'ú' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x18, /* 00011000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 251 0xfb 'û' */
- 0x00, /* 00000000 */
- 0x0f, /* 00001111 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0x0c, /* 00001100 */
- 0xec, /* 11101100 */
- 0x6c, /* 01101100 */
- 0x6c, /* 01101100 */
- 0x3c, /* 00111100 */
- 0x1c, /* 00011100 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 252 0xfc 'ü' */
- 0x00, /* 00000000 */
- 0x6c, /* 01101100 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x36, /* 00110110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 253 0xfd 'ý' */
- 0x00, /* 00000000 */
- 0x3c, /* 00111100 */
- 0x66, /* 01100110 */
- 0x0c, /* 00001100 */
- 0x18, /* 00011000 */
- 0x32, /* 00110010 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 254 0xfe 'þ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x7e, /* 01111110 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
- /* 255 0xff 'ÿ' */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
- 0x00, /* 00000000 */
-
-};
diff --git a/qemu/ui/vnc-auth-sasl.c b/qemu/ui/vnc-auth-sasl.c
deleted file mode 100644
index 5ae29c14c..000000000
--- a/qemu/ui/vnc-auth-sasl.c
+++ /dev/null
@@ -1,660 +0,0 @@
-/*
- * QEMU VNC display driver: SASL auth protocol
- *
- * Copyright (C) 2009 Red Hat, Inc
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "vnc.h"
-
-/* Max amount of data we send/recv for SASL steps to prevent DOS */
-#define SASL_DATA_MAX_LEN (1024 * 1024)
-
-
-void vnc_sasl_client_cleanup(VncState *vs)
-{
- if (vs->sasl.conn) {
- vs->sasl.runSSF = false;
- vs->sasl.wantSSF = false;
- vs->sasl.waitWriteSSF = 0;
- vs->sasl.encodedLength = vs->sasl.encodedOffset = 0;
- vs->sasl.encoded = NULL;
- g_free(vs->sasl.username);
- g_free(vs->sasl.mechlist);
- vs->sasl.username = vs->sasl.mechlist = NULL;
- sasl_dispose(&vs->sasl.conn);
- vs->sasl.conn = NULL;
- }
-}
-
-
-long vnc_client_write_sasl(VncState *vs)
-{
- long ret;
-
- VNC_DEBUG("Write SASL: Pending output %p size %zd offset %zd "
- "Encoded: %p size %d offset %d\n",
- vs->output.buffer, vs->output.capacity, vs->output.offset,
- vs->sasl.encoded, vs->sasl.encodedLength, vs->sasl.encodedOffset);
-
- if (!vs->sasl.encoded) {
- int err;
- err = sasl_encode(vs->sasl.conn,
- (char *)vs->output.buffer,
- vs->output.offset,
- (const char **)&vs->sasl.encoded,
- &vs->sasl.encodedLength);
- if (err != SASL_OK)
- return vnc_client_io_error(vs, -1, NULL);
-
- vs->sasl.encodedOffset = 0;
- }
-
- ret = vnc_client_write_buf(vs,
- vs->sasl.encoded + vs->sasl.encodedOffset,
- vs->sasl.encodedLength - vs->sasl.encodedOffset);
- if (!ret)
- return 0;
-
- vs->sasl.encodedOffset += ret;
- if (vs->sasl.encodedOffset == vs->sasl.encodedLength) {
- vs->output.offset = 0;
- vs->sasl.encoded = NULL;
- vs->sasl.encodedOffset = vs->sasl.encodedLength = 0;
- }
-
- /* Can't merge this block with one above, because
- * someone might have written more unencrypted
- * data in vs->output while we were processing
- * SASL encoded output
- */
- if (vs->output.offset == 0) {
- if (vs->ioc_tag) {
- g_source_remove(vs->ioc_tag);
- }
- vs->ioc_tag = qio_channel_add_watch(
- vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
- }
-
- return ret;
-}
-
-
-long vnc_client_read_sasl(VncState *vs)
-{
- long ret;
- uint8_t encoded[4096];
- const char *decoded;
- unsigned int decodedLen;
- int err;
-
- ret = vnc_client_read_buf(vs, encoded, sizeof(encoded));
- if (!ret)
- return 0;
-
- err = sasl_decode(vs->sasl.conn,
- (char *)encoded, ret,
- &decoded, &decodedLen);
-
- if (err != SASL_OK)
- return vnc_client_io_error(vs, -1, NULL);
- VNC_DEBUG("Read SASL Encoded %p size %ld Decoded %p size %d\n",
- encoded, ret, decoded, decodedLen);
- buffer_reserve(&vs->input, decodedLen);
- buffer_append(&vs->input, decoded, decodedLen);
- return decodedLen;
-}
-
-
-static int vnc_auth_sasl_check_access(VncState *vs)
-{
- const void *val;
- int err;
- int allow;
-
- err = sasl_getprop(vs->sasl.conn, SASL_USERNAME, &val);
- if (err != SASL_OK) {
- VNC_DEBUG("cannot query SASL username on connection %d (%s), denying access\n",
- err, sasl_errstring(err, NULL, NULL));
- return -1;
- }
- if (val == NULL) {
- VNC_DEBUG("no client username was found, denying access\n");
- return -1;
- }
- VNC_DEBUG("SASL client username %s\n", (const char *)val);
-
- vs->sasl.username = g_strdup((const char*)val);
-
- if (vs->vd->sasl.acl == NULL) {
- VNC_DEBUG("no ACL activated, allowing access\n");
- return 0;
- }
-
- allow = qemu_acl_party_is_allowed(vs->vd->sasl.acl, vs->sasl.username);
-
- VNC_DEBUG("SASL client %s %s by ACL\n", vs->sasl.username,
- allow ? "allowed" : "denied");
- return allow ? 0 : -1;
-}
-
-static int vnc_auth_sasl_check_ssf(VncState *vs)
-{
- const void *val;
- int err, ssf;
-
- if (!vs->sasl.wantSSF)
- return 1;
-
- err = sasl_getprop(vs->sasl.conn, SASL_SSF, &val);
- if (err != SASL_OK)
- return 0;
-
- ssf = *(const int *)val;
- VNC_DEBUG("negotiated an SSF of %d\n", ssf);
- if (ssf < 56)
- return 0; /* 56 is good for Kerberos */
-
- /* Only setup for read initially, because we're about to send an RPC
- * reply which must be in plain text. When the next incoming RPC
- * arrives, we'll switch on writes too
- *
- * cf qemudClientReadSASL in qemud.c
- */
- vs->sasl.runSSF = 1;
-
- /* We have a SSF that's good enough */
- return 1;
-}
-
-/*
- * Step Msg
- *
- * Input from client:
- *
- * u32 clientin-length
- * u8-array clientin-string
- *
- * Output to client:
- *
- * u32 serverout-length
- * u8-array serverout-strin
- * u8 continue
- */
-
-static int protocol_client_auth_sasl_step_len(VncState *vs, uint8_t *data, size_t len);
-
-static int protocol_client_auth_sasl_step(VncState *vs, uint8_t *data, size_t len)
-{
- uint32_t datalen = len;
- const char *serverout;
- unsigned int serveroutlen;
- int err;
- char *clientdata = NULL;
-
- /* NB, distinction of NULL vs "" is *critical* in SASL */
- if (datalen) {
- clientdata = (char*)data;
- clientdata[datalen-1] = '\0'; /* Wire includes '\0', but make sure */
- datalen--; /* Don't count NULL byte when passing to _start() */
- }
-
- VNC_DEBUG("Step using SASL Data %p (%d bytes)\n",
- clientdata, datalen);
- err = sasl_server_step(vs->sasl.conn,
- clientdata,
- datalen,
- &serverout,
- &serveroutlen);
- if (err != SASL_OK &&
- err != SASL_CONTINUE) {
- VNC_DEBUG("sasl step failed %d (%s)\n",
- err, sasl_errdetail(vs->sasl.conn));
- sasl_dispose(&vs->sasl.conn);
- vs->sasl.conn = NULL;
- goto authabort;
- }
-
- if (serveroutlen > SASL_DATA_MAX_LEN) {
- VNC_DEBUG("sasl step reply data too long %d\n",
- serveroutlen);
- sasl_dispose(&vs->sasl.conn);
- vs->sasl.conn = NULL;
- goto authabort;
- }
-
- VNC_DEBUG("SASL return data %d bytes, nil; %d\n",
- serveroutlen, serverout ? 0 : 1);
-
- if (serveroutlen) {
- vnc_write_u32(vs, serveroutlen + 1);
- vnc_write(vs, serverout, serveroutlen + 1);
- } else {
- vnc_write_u32(vs, 0);
- }
-
- /* Whether auth is complete */
- vnc_write_u8(vs, err == SASL_CONTINUE ? 0 : 1);
-
- if (err == SASL_CONTINUE) {
- VNC_DEBUG("%s", "Authentication must continue\n");
- /* Wait for step length */
- vnc_read_when(vs, protocol_client_auth_sasl_step_len, 4);
- } else {
- if (!vnc_auth_sasl_check_ssf(vs)) {
- VNC_DEBUG("Authentication rejected for weak SSF %p\n", vs->ioc);
- goto authreject;
- }
-
- /* Check username whitelist ACL */
- if (vnc_auth_sasl_check_access(vs) < 0) {
- VNC_DEBUG("Authentication rejected for ACL %p\n", vs->ioc);
- goto authreject;
- }
-
- VNC_DEBUG("Authentication successful %p\n", vs->ioc);
- vnc_write_u32(vs, 0); /* Accept auth */
- /*
- * Delay writing in SSF encoded mode until pending output
- * buffer is written
- */
- if (vs->sasl.runSSF)
- vs->sasl.waitWriteSSF = vs->output.offset;
- start_client_init(vs);
- }
-
- return 0;
-
- authreject:
- vnc_write_u32(vs, 1); /* Reject auth */
- vnc_write_u32(vs, sizeof("Authentication failed"));
- vnc_write(vs, "Authentication failed", sizeof("Authentication failed"));
- vnc_flush(vs);
- vnc_client_error(vs);
- return -1;
-
- authabort:
- vnc_client_error(vs);
- return -1;
-}
-
-static int protocol_client_auth_sasl_step_len(VncState *vs, uint8_t *data, size_t len)
-{
- uint32_t steplen = read_u32(data, 0);
- VNC_DEBUG("Got client step len %d\n", steplen);
- if (steplen > SASL_DATA_MAX_LEN) {
- VNC_DEBUG("Too much SASL data %d\n", steplen);
- vnc_client_error(vs);
- return -1;
- }
-
- if (steplen == 0)
- return protocol_client_auth_sasl_step(vs, NULL, 0);
- else
- vnc_read_when(vs, protocol_client_auth_sasl_step, steplen);
- return 0;
-}
-
-/*
- * Start Msg
- *
- * Input from client:
- *
- * u32 clientin-length
- * u8-array clientin-string
- *
- * Output to client:
- *
- * u32 serverout-length
- * u8-array serverout-strin
- * u8 continue
- */
-
-#define SASL_DATA_MAX_LEN (1024 * 1024)
-
-static int protocol_client_auth_sasl_start(VncState *vs, uint8_t *data, size_t len)
-{
- uint32_t datalen = len;
- const char *serverout;
- unsigned int serveroutlen;
- int err;
- char *clientdata = NULL;
-
- /* NB, distinction of NULL vs "" is *critical* in SASL */
- if (datalen) {
- clientdata = (char*)data;
- clientdata[datalen-1] = '\0'; /* Should be on wire, but make sure */
- datalen--; /* Don't count NULL byte when passing to _start() */
- }
-
- VNC_DEBUG("Start SASL auth with mechanism %s. Data %p (%d bytes)\n",
- vs->sasl.mechlist, clientdata, datalen);
- err = sasl_server_start(vs->sasl.conn,
- vs->sasl.mechlist,
- clientdata,
- datalen,
- &serverout,
- &serveroutlen);
- if (err != SASL_OK &&
- err != SASL_CONTINUE) {
- VNC_DEBUG("sasl start failed %d (%s)\n",
- err, sasl_errdetail(vs->sasl.conn));
- sasl_dispose(&vs->sasl.conn);
- vs->sasl.conn = NULL;
- goto authabort;
- }
- if (serveroutlen > SASL_DATA_MAX_LEN) {
- VNC_DEBUG("sasl start reply data too long %d\n",
- serveroutlen);
- sasl_dispose(&vs->sasl.conn);
- vs->sasl.conn = NULL;
- goto authabort;
- }
-
- VNC_DEBUG("SASL return data %d bytes, nil; %d\n",
- serveroutlen, serverout ? 0 : 1);
-
- if (serveroutlen) {
- vnc_write_u32(vs, serveroutlen + 1);
- vnc_write(vs, serverout, serveroutlen + 1);
- } else {
- vnc_write_u32(vs, 0);
- }
-
- /* Whether auth is complete */
- vnc_write_u8(vs, err == SASL_CONTINUE ? 0 : 1);
-
- if (err == SASL_CONTINUE) {
- VNC_DEBUG("%s", "Authentication must continue\n");
- /* Wait for step length */
- vnc_read_when(vs, protocol_client_auth_sasl_step_len, 4);
- } else {
- if (!vnc_auth_sasl_check_ssf(vs)) {
- VNC_DEBUG("Authentication rejected for weak SSF %p\n", vs->ioc);
- goto authreject;
- }
-
- /* Check username whitelist ACL */
- if (vnc_auth_sasl_check_access(vs) < 0) {
- VNC_DEBUG("Authentication rejected for ACL %p\n", vs->ioc);
- goto authreject;
- }
-
- VNC_DEBUG("Authentication successful %p\n", vs->ioc);
- vnc_write_u32(vs, 0); /* Accept auth */
- start_client_init(vs);
- }
-
- return 0;
-
- authreject:
- vnc_write_u32(vs, 1); /* Reject auth */
- vnc_write_u32(vs, sizeof("Authentication failed"));
- vnc_write(vs, "Authentication failed", sizeof("Authentication failed"));
- vnc_flush(vs);
- vnc_client_error(vs);
- return -1;
-
- authabort:
- vnc_client_error(vs);
- return -1;
-}
-
-static int protocol_client_auth_sasl_start_len(VncState *vs, uint8_t *data, size_t len)
-{
- uint32_t startlen = read_u32(data, 0);
- VNC_DEBUG("Got client start len %d\n", startlen);
- if (startlen > SASL_DATA_MAX_LEN) {
- VNC_DEBUG("Too much SASL data %d\n", startlen);
- vnc_client_error(vs);
- return -1;
- }
-
- if (startlen == 0)
- return protocol_client_auth_sasl_start(vs, NULL, 0);
-
- vnc_read_when(vs, protocol_client_auth_sasl_start, startlen);
- return 0;
-}
-
-static int protocol_client_auth_sasl_mechname(VncState *vs, uint8_t *data, size_t len)
-{
- char *mechname = g_strndup((const char *) data, len);
- VNC_DEBUG("Got client mechname '%s' check against '%s'\n",
- mechname, vs->sasl.mechlist);
-
- if (strncmp(vs->sasl.mechlist, mechname, len) == 0) {
- if (vs->sasl.mechlist[len] != '\0' &&
- vs->sasl.mechlist[len] != ',') {
- VNC_DEBUG("One %d", vs->sasl.mechlist[len]);
- goto fail;
- }
- } else {
- char *offset = strstr(vs->sasl.mechlist, mechname);
- VNC_DEBUG("Two %p\n", offset);
- if (!offset) {
- goto fail;
- }
- VNC_DEBUG("Two '%s'\n", offset);
- if (offset[-1] != ',' ||
- (offset[len] != '\0'&&
- offset[len] != ',')) {
- goto fail;
- }
- }
-
- g_free(vs->sasl.mechlist);
- vs->sasl.mechlist = mechname;
-
- VNC_DEBUG("Validated mechname '%s'\n", mechname);
- vnc_read_when(vs, protocol_client_auth_sasl_start_len, 4);
- return 0;
-
- fail:
- vnc_client_error(vs);
- g_free(mechname);
- return -1;
-}
-
-static int protocol_client_auth_sasl_mechname_len(VncState *vs, uint8_t *data, size_t len)
-{
- uint32_t mechlen = read_u32(data, 0);
- VNC_DEBUG("Got client mechname len %d\n", mechlen);
- if (mechlen > 100) {
- VNC_DEBUG("Too long SASL mechname data %d\n", mechlen);
- vnc_client_error(vs);
- return -1;
- }
- if (mechlen < 1) {
- VNC_DEBUG("Too short SASL mechname %d\n", mechlen);
- vnc_client_error(vs);
- return -1;
- }
- vnc_read_when(vs, protocol_client_auth_sasl_mechname,mechlen);
- return 0;
-}
-
-static char *
-vnc_socket_ip_addr_string(QIOChannelSocket *ioc,
- bool local,
- Error **errp)
-{
- SocketAddress *addr;
- char *ret;
-
- if (local) {
- addr = qio_channel_socket_get_local_address(ioc, errp);
- } else {
- addr = qio_channel_socket_get_remote_address(ioc, errp);
- }
- if (!addr) {
- return NULL;
- }
-
- if (addr->type != SOCKET_ADDRESS_KIND_INET) {
- error_setg(errp, "Not an inet socket type");
- return NULL;
- }
- ret = g_strdup_printf("%s;%s", addr->u.inet.data->host,
- addr->u.inet.data->port);
- qapi_free_SocketAddress(addr);
- return ret;
-}
-
-void start_auth_sasl(VncState *vs)
-{
- const char *mechlist = NULL;
- sasl_security_properties_t secprops;
- int err;
- char *localAddr, *remoteAddr;
- int mechlistlen;
-
- VNC_DEBUG("Initialize SASL auth %p\n", vs->ioc);
-
- /* Get local & remote client addresses in form IPADDR;PORT */
- localAddr = vnc_socket_ip_addr_string(vs->sioc, true, NULL);
- if (!localAddr) {
- goto authabort;
- }
-
- remoteAddr = vnc_socket_ip_addr_string(vs->sioc, false, NULL);
- if (!remoteAddr) {
- g_free(localAddr);
- goto authabort;
- }
-
- err = sasl_server_new("vnc",
- NULL, /* FQDN - just delegates to gethostname */
- NULL, /* User realm */
- localAddr,
- remoteAddr,
- NULL, /* Callbacks, not needed */
- SASL_SUCCESS_DATA,
- &vs->sasl.conn);
- g_free(localAddr);
- g_free(remoteAddr);
- localAddr = remoteAddr = NULL;
-
- if (err != SASL_OK) {
- VNC_DEBUG("sasl context setup failed %d (%s)",
- err, sasl_errstring(err, NULL, NULL));
- vs->sasl.conn = NULL;
- goto authabort;
- }
-
- /* Inform SASL that we've got an external SSF layer from TLS/x509 */
- if (vs->auth == VNC_AUTH_VENCRYPT &&
- vs->subauth == VNC_AUTH_VENCRYPT_X509SASL) {
- Error *local_err = NULL;
- int keysize;
- sasl_ssf_t ssf;
-
- keysize = qcrypto_tls_session_get_key_size(vs->tls,
- &local_err);
- if (keysize < 0) {
- VNC_DEBUG("cannot TLS get cipher size: %s\n",
- error_get_pretty(local_err));
- error_free(local_err);
- sasl_dispose(&vs->sasl.conn);
- vs->sasl.conn = NULL;
- goto authabort;
- }
- ssf = keysize * CHAR_BIT; /* tls key size is bytes, sasl wants bits */
-
- err = sasl_setprop(vs->sasl.conn, SASL_SSF_EXTERNAL, &ssf);
- if (err != SASL_OK) {
- VNC_DEBUG("cannot set SASL external SSF %d (%s)\n",
- err, sasl_errstring(err, NULL, NULL));
- sasl_dispose(&vs->sasl.conn);
- vs->sasl.conn = NULL;
- goto authabort;
- }
- } else {
- vs->sasl.wantSSF = 1;
- }
-
- memset (&secprops, 0, sizeof secprops);
- /* Inform SASL that we've got an external SSF layer from TLS.
- *
- * Disable SSF, if using TLS+x509+SASL only. TLS without x509
- * is not sufficiently strong
- */
- if (vs->vd->is_unix ||
- (vs->auth == VNC_AUTH_VENCRYPT &&
- vs->subauth == VNC_AUTH_VENCRYPT_X509SASL)) {
- /* If we've got TLS or UNIX domain sock, we don't care about SSF */
- secprops.min_ssf = 0;
- secprops.max_ssf = 0;
- secprops.maxbufsize = 8192;
- secprops.security_flags = 0;
- } else {
- /* Plain TCP, better get an SSF layer */
- secprops.min_ssf = 56; /* Good enough to require kerberos */
- secprops.max_ssf = 100000; /* Arbitrary big number */
- secprops.maxbufsize = 8192;
- /* Forbid any anonymous or trivially crackable auth */
- secprops.security_flags =
- SASL_SEC_NOANONYMOUS | SASL_SEC_NOPLAINTEXT;
- }
-
- err = sasl_setprop(vs->sasl.conn, SASL_SEC_PROPS, &secprops);
- if (err != SASL_OK) {
- VNC_DEBUG("cannot set SASL security props %d (%s)\n",
- err, sasl_errstring(err, NULL, NULL));
- sasl_dispose(&vs->sasl.conn);
- vs->sasl.conn = NULL;
- goto authabort;
- }
-
- err = sasl_listmech(vs->sasl.conn,
- NULL, /* Don't need to set user */
- "", /* Prefix */
- ",", /* Separator */
- "", /* Suffix */
- &mechlist,
- NULL,
- NULL);
- if (err != SASL_OK) {
- VNC_DEBUG("cannot list SASL mechanisms %d (%s)\n",
- err, sasl_errdetail(vs->sasl.conn));
- sasl_dispose(&vs->sasl.conn);
- vs->sasl.conn = NULL;
- goto authabort;
- }
- VNC_DEBUG("Available mechanisms for client: '%s'\n", mechlist);
-
- vs->sasl.mechlist = g_strdup(mechlist);
- mechlistlen = strlen(mechlist);
- vnc_write_u32(vs, mechlistlen);
- vnc_write(vs, mechlist, mechlistlen);
- vnc_flush(vs);
-
- VNC_DEBUG("Wait for client mechname length\n");
- vnc_read_when(vs, protocol_client_auth_sasl_mechname_len, 4);
-
- return;
-
- authabort:
- vnc_client_error(vs);
-}
-
-
diff --git a/qemu/ui/vnc-auth-sasl.h b/qemu/ui/vnc-auth-sasl.h
deleted file mode 100644
index 3f59da67e..000000000
--- a/qemu/ui/vnc-auth-sasl.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * QEMU VNC display driver: SASL auth protocol
- *
- * Copyright (C) 2009 Red Hat, Inc
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-
-#ifndef __QEMU_VNC_AUTH_SASL_H__
-#define __QEMU_VNC_AUTH_SASL_H__
-
-
-#include <sasl/sasl.h>
-
-typedef struct VncStateSASL VncStateSASL;
-typedef struct VncDisplaySASL VncDisplaySASL;
-
-#include "qemu/acl.h"
-#include "qemu/main-loop.h"
-
-struct VncStateSASL {
- sasl_conn_t *conn;
- /* If we want to negotiate an SSF layer with client */
- bool wantSSF;
- /* If we are now running the SSF layer */
- bool runSSF;
- /*
- * If this is non-zero, then wait for that many bytes
- * to be written plain, before switching to SSF encoding
- * This allows the VNC auth result to finish being
- * written in plain.
- */
- unsigned int waitWriteSSF;
-
- /*
- * Buffering encoded data to allow more clear data
- * to be stuffed onto the output buffer
- */
- const uint8_t *encoded;
- unsigned int encodedLength;
- unsigned int encodedOffset;
- char *username;
- char *mechlist;
-};
-
-struct VncDisplaySASL {
- qemu_acl *acl;
-};
-
-void vnc_sasl_client_cleanup(VncState *vs);
-
-long vnc_client_read_sasl(VncState *vs);
-long vnc_client_write_sasl(VncState *vs);
-
-void start_auth_sasl(VncState *vs);
-
-#endif /* __QEMU_VNC_AUTH_SASL_H__ */
-
diff --git a/qemu/ui/vnc-auth-vencrypt.c b/qemu/ui/vnc-auth-vencrypt.c
deleted file mode 100644
index 11c8c9a81..000000000
--- a/qemu/ui/vnc-auth-vencrypt.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * QEMU VNC display driver: VeNCrypt authentication setup
- *
- * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
- * Copyright (C) 2006 Fabrice Bellard
- * Copyright (C) 2009 Red Hat, Inc
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "vnc.h"
-#include "qapi/error.h"
-#include "qemu/main-loop.h"
-
-static void start_auth_vencrypt_subauth(VncState *vs)
-{
- switch (vs->subauth) {
- case VNC_AUTH_VENCRYPT_TLSNONE:
- case VNC_AUTH_VENCRYPT_X509NONE:
- VNC_DEBUG("Accept TLS auth none\n");
- vnc_write_u32(vs, 0); /* Accept auth completion */
- start_client_init(vs);
- break;
-
- case VNC_AUTH_VENCRYPT_TLSVNC:
- case VNC_AUTH_VENCRYPT_X509VNC:
- VNC_DEBUG("Start TLS auth VNC\n");
- start_auth_vnc(vs);
- break;
-
-#ifdef CONFIG_VNC_SASL
- case VNC_AUTH_VENCRYPT_TLSSASL:
- case VNC_AUTH_VENCRYPT_X509SASL:
- VNC_DEBUG("Start TLS auth SASL\n");
- start_auth_sasl(vs);
- break;
-#endif /* CONFIG_VNC_SASL */
-
- default: /* Should not be possible, but just in case */
- VNC_DEBUG("Reject subauth %d server bug\n", vs->auth);
- vnc_write_u8(vs, 1);
- if (vs->minor >= 8) {
- static const char err[] = "Unsupported authentication type";
- vnc_write_u32(vs, sizeof(err));
- vnc_write(vs, err, sizeof(err));
- }
- vnc_client_error(vs);
- }
-}
-
-static void vnc_tls_handshake_done(Object *source,
- Error *err,
- gpointer user_data)
-{
- VncState *vs = user_data;
-
- if (err) {
- VNC_DEBUG("Handshake failed %s\n",
- error_get_pretty(err));
- vnc_client_error(vs);
- } else {
- vs->ioc_tag = qio_channel_add_watch(
- vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
- start_auth_vencrypt_subauth(vs);
- }
-}
-
-
-static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
-{
- int auth = read_u32(data, 0);
-
- if (auth != vs->subauth) {
- VNC_DEBUG("Rejecting auth %d\n", auth);
- vnc_write_u8(vs, 0); /* Reject auth */
- vnc_flush(vs);
- vnc_client_error(vs);
- } else {
- Error *err = NULL;
- QIOChannelTLS *tls;
- VNC_DEBUG("Accepting auth %d, setting up TLS for handshake\n", auth);
- vnc_write_u8(vs, 1); /* Accept auth */
- vnc_flush(vs);
-
- if (vs->ioc_tag) {
- g_source_remove(vs->ioc_tag);
- vs->ioc_tag = 0;
- }
-
- tls = qio_channel_tls_new_server(
- vs->ioc,
- vs->vd->tlscreds,
- vs->vd->tlsaclname,
- &err);
- if (!tls) {
- VNC_DEBUG("Failed to setup TLS %s\n", error_get_pretty(err));
- error_free(err);
- vnc_client_error(vs);
- return 0;
- }
-
- VNC_DEBUG("Start TLS VeNCrypt handshake process\n");
- object_unref(OBJECT(vs->ioc));
- vs->ioc = QIO_CHANNEL(tls);
- vs->tls = qio_channel_tls_get_session(tls);
-
- qio_channel_tls_handshake(tls,
- vnc_tls_handshake_done,
- vs,
- NULL);
- }
- return 0;
-}
-
-static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)
-{
- if (data[0] != 0 ||
- data[1] != 2) {
- VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);
- vnc_write_u8(vs, 1); /* Reject version */
- vnc_flush(vs);
- vnc_client_error(vs);
- } else {
- VNC_DEBUG("Sending allowed auth %d\n", vs->subauth);
- vnc_write_u8(vs, 0); /* Accept version */
- vnc_write_u8(vs, 1); /* Number of sub-auths */
- vnc_write_u32(vs, vs->subauth); /* The supported auth */
- vnc_flush(vs);
- vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
- }
- return 0;
-}
-
-
-void start_auth_vencrypt(VncState *vs)
-{
- /* Send VeNCrypt version 0.2 */
- vnc_write_u8(vs, 0);
- vnc_write_u8(vs, 2);
-
- vnc_read_when(vs, protocol_client_vencrypt_init, 2);
-}
-
diff --git a/qemu/ui/vnc-auth-vencrypt.h b/qemu/ui/vnc-auth-vencrypt.h
deleted file mode 100644
index 9f674c517..000000000
--- a/qemu/ui/vnc-auth-vencrypt.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * QEMU VNC display driver
- *
- * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
- * Copyright (C) 2006 Fabrice Bellard
- * Copyright (C) 2009 Red Hat, Inc
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-
-#ifndef __QEMU_VNC_AUTH_VENCRYPT_H__
-#define __QEMU_VNC_AUTH_VENCRYPT_H__
-
-void start_auth_vencrypt(VncState *vs);
-
-#endif /* __QEMU_VNC_AUTH_VENCRYPT_H__ */
diff --git a/qemu/ui/vnc-enc-hextile-template.h b/qemu/ui/vnc-enc-hextile-template.h
deleted file mode 100644
index d868d7572..000000000
--- a/qemu/ui/vnc-enc-hextile-template.h
+++ /dev/null
@@ -1,211 +0,0 @@
-#define CONCAT_I(a, b) a ## b
-#define CONCAT(a, b) CONCAT_I(a, b)
-#define pixel_t CONCAT(uint, CONCAT(BPP, _t))
-#ifdef GENERIC
-#define NAME CONCAT(generic_, BPP)
-#else
-#define NAME BPP
-#endif
-
-static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
- int x, int y, int w, int h,
- void *last_bg_,
- void *last_fg_,
- int *has_bg, int *has_fg)
-{
- VncDisplay *vd = vs->vd;
- uint8_t *row = vnc_server_fb_ptr(vd, x, y);
- pixel_t *irow = (pixel_t *)row;
- int j, i;
- pixel_t *last_bg = (pixel_t *)last_bg_;
- pixel_t *last_fg = (pixel_t *)last_fg_;
- pixel_t bg = 0;
- pixel_t fg = 0;
- int n_colors = 0;
- int bg_count = 0;
- int fg_count = 0;
- int flags = 0;
- uint8_t data[(vs->client_pf.bytes_per_pixel + 2) * 16 * 16];
- int n_data = 0;
- int n_subtiles = 0;
-
- for (j = 0; j < h; j++) {
- for (i = 0; i < w; i++) {
- switch (n_colors) {
- case 0:
- bg = irow[i];
- n_colors = 1;
- break;
- case 1:
- if (irow[i] != bg) {
- fg = irow[i];
- n_colors = 2;
- }
- break;
- case 2:
- if (irow[i] != bg && irow[i] != fg) {
- n_colors = 3;
- } else {
- if (irow[i] == bg)
- bg_count++;
- else if (irow[i] == fg)
- fg_count++;
- }
- break;
- default:
- break;
- }
- }
- if (n_colors > 2)
- break;
- irow += vnc_server_fb_stride(vd) / sizeof(pixel_t);
- }
-
- if (n_colors > 1 && fg_count > bg_count) {
- pixel_t tmp = fg;
- fg = bg;
- bg = tmp;
- }
-
- if (!*has_bg || *last_bg != bg) {
- flags |= 0x02;
- *has_bg = 1;
- *last_bg = bg;
- }
-
- if (n_colors < 3 && (!*has_fg || *last_fg != fg)) {
- flags |= 0x04;
- *has_fg = 1;
- *last_fg = fg;
- }
-
- switch (n_colors) {
- case 1:
- n_data = 0;
- break;
- case 2:
- flags |= 0x08;
-
- irow = (pixel_t *)row;
-
- for (j = 0; j < h; j++) {
- int min_x = -1;
- for (i = 0; i < w; i++) {
- if (irow[i] == fg) {
- if (min_x == -1)
- min_x = i;
- } else if (min_x != -1) {
- hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
- n_data += 2;
- n_subtiles++;
- min_x = -1;
- }
- }
- if (min_x != -1) {
- hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
- n_data += 2;
- n_subtiles++;
- }
- irow += vnc_server_fb_stride(vd) / sizeof(pixel_t);
- }
- break;
- case 3:
- flags |= 0x18;
-
- irow = (pixel_t *)row;
-
- if (!*has_bg || *last_bg != bg)
- flags |= 0x02;
-
- for (j = 0; j < h; j++) {
- int has_color = 0;
- int min_x = -1;
- pixel_t color = 0; /* shut up gcc */
-
- for (i = 0; i < w; i++) {
- if (!has_color) {
- if (irow[i] == bg)
- continue;
- color = irow[i];
- min_x = i;
- has_color = 1;
- } else if (irow[i] != color) {
- has_color = 0;
-#ifdef GENERIC
- vnc_convert_pixel(vs, data + n_data, color);
- n_data += vs->client_pf.bytes_per_pixel;
-#else
- memcpy(data + n_data, &color, sizeof(color));
- n_data += sizeof(pixel_t);
-#endif
- hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
- n_data += 2;
- n_subtiles++;
-
- min_x = -1;
- if (irow[i] != bg) {
- color = irow[i];
- min_x = i;
- has_color = 1;
- }
- }
- }
- if (has_color) {
-#ifdef GENERIC
- vnc_convert_pixel(vs, data + n_data, color);
- n_data += vs->client_pf.bytes_per_pixel;
-#else
- memcpy(data + n_data, &color, sizeof(color));
- n_data += sizeof(pixel_t);
-#endif
- hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1);
- n_data += 2;
- n_subtiles++;
- }
- irow += vnc_server_fb_stride(vd) / sizeof(pixel_t);
- }
-
- /* A SubrectsColoured subtile invalidates the foreground color */
- *has_fg = 0;
- if (n_data > (w * h * sizeof(pixel_t))) {
- n_colors = 4;
- flags = 0x01;
- *has_bg = 0;
-
- /* we really don't have to invalidate either the bg or fg
- but we've lost the old values. oh well. */
- }
- break;
- default:
- break;
- }
-
- if (n_colors > 3) {
- flags = 0x01;
- *has_fg = 0;
- *has_bg = 0;
- n_colors = 4;
- }
-
- vnc_write_u8(vs, flags);
- if (n_colors < 4) {
- if (flags & 0x02)
- vs->write_pixels(vs, last_bg, sizeof(pixel_t));
- if (flags & 0x04)
- vs->write_pixels(vs, last_fg, sizeof(pixel_t));
- if (n_subtiles) {
- vnc_write_u8(vs, n_subtiles);
- vnc_write(vs, data, n_data);
- }
- } else {
- for (j = 0; j < h; j++) {
- vs->write_pixels(vs, row, w * 4);
- row += vnc_server_fb_stride(vd);
- }
- }
-}
-
-#undef NAME
-#undef pixel_t
-#undef CONCAT_I
-#undef CONCAT
diff --git a/qemu/ui/vnc-enc-hextile.c b/qemu/ui/vnc-enc-hextile.c
deleted file mode 100644
index 4215bd7da..000000000
--- a/qemu/ui/vnc-enc-hextile.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * QEMU VNC display driver: hextile encoding
- *
- * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
- * Copyright (C) 2006 Fabrice Bellard
- * Copyright (C) 2009 Red Hat, Inc
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "vnc.h"
-
-static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
-{
- ptr[0] = ((x & 0x0F) << 4) | (y & 0x0F);
- ptr[1] = (((w - 1) & 0x0F) << 4) | ((h - 1) & 0x0F);
-}
-
-#define BPP 32
-#include "vnc-enc-hextile-template.h"
-#undef BPP
-
-#define GENERIC
-#define BPP 32
-#include "vnc-enc-hextile-template.h"
-#undef BPP
-#undef GENERIC
-
-int vnc_hextile_send_framebuffer_update(VncState *vs, int x,
- int y, int w, int h)
-{
- int i, j;
- int has_fg, has_bg;
- uint8_t *last_fg, *last_bg;
-
- last_fg = (uint8_t *) g_malloc(VNC_SERVER_FB_BYTES);
- last_bg = (uint8_t *) g_malloc(VNC_SERVER_FB_BYTES);
- has_fg = has_bg = 0;
- for (j = y; j < (y + h); j += 16) {
- for (i = x; i < (x + w); i += 16) {
- vs->hextile.send_tile(vs, i, j,
- MIN(16, x + w - i), MIN(16, y + h - j),
- last_bg, last_fg, &has_bg, &has_fg);
- }
- }
- g_free(last_fg);
- g_free(last_bg);
-
- return 1;
-}
-
-void vnc_hextile_set_pixel_conversion(VncState *vs, int generic)
-{
- if (!generic) {
- switch (VNC_SERVER_FB_BITS) {
- case 32:
- vs->hextile.send_tile = send_hextile_tile_32;
- break;
- }
- } else {
- switch (VNC_SERVER_FB_BITS) {
- case 32:
- vs->hextile.send_tile = send_hextile_tile_generic_32;
- break;
- }
- }
-}
diff --git a/qemu/ui/vnc-enc-tight.c b/qemu/ui/vnc-enc-tight.c
deleted file mode 100644
index e5cba0e5a..000000000
--- a/qemu/ui/vnc-enc-tight.c
+++ /dev/null
@@ -1,1697 +0,0 @@
-/*
- * QEMU VNC display driver: tight encoding
- *
- * From libvncserver/libvncserver/tight.c
- * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved.
- * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
- *
- * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-
-/* This needs to be before jpeglib.h line because of conflict with
- INT32 definitions between jmorecfg.h (included by jpeglib.h) and
- Win32 basetsd.h (included by windows.h). */
-#include "qemu-common.h"
-
-#ifdef CONFIG_VNC_PNG
-/* The following define is needed by pngconf.h. Otherwise it won't compile,
- because setjmp.h was already included by qemu-common.h. */
-#define PNG_SKIP_SETJMP_CHECK
-#include <png.h>
-#endif
-#ifdef CONFIG_VNC_JPEG
-#include <jpeglib.h>
-#endif
-
-#include "qemu/bswap.h"
-#include "qapi/qmp/qint.h"
-#include "vnc.h"
-#include "vnc-enc-tight.h"
-#include "vnc-palette.h"
-
-/* Compression level stuff. The following array contains various
- encoder parameters for each of 10 compression levels (0..9).
- Last three parameters correspond to JPEG quality levels (0..9). */
-
-static const struct {
- int max_rect_size, max_rect_width;
- int mono_min_rect_size, gradient_min_rect_size;
- int idx_zlib_level, mono_zlib_level, raw_zlib_level, gradient_zlib_level;
- int gradient_threshold, gradient_threshold24;
- int idx_max_colors_divisor;
- int jpeg_quality, jpeg_threshold, jpeg_threshold24;
-} tight_conf[] = {
- { 512, 32, 6, 65536, 0, 0, 0, 0, 0, 0, 4, 5, 10000, 23000 },
- { 2048, 128, 6, 65536, 1, 1, 1, 0, 0, 0, 8, 10, 8000, 18000 },
- { 6144, 256, 8, 65536, 3, 3, 2, 0, 0, 0, 24, 15, 6500, 15000 },
- { 10240, 1024, 12, 65536, 5, 5, 3, 0, 0, 0, 32, 25, 5000, 12000 },
- { 16384, 2048, 12, 65536, 6, 6, 4, 0, 0, 0, 32, 37, 4000, 10000 },
- { 32768, 2048, 12, 4096, 7, 7, 5, 4, 150, 380, 32, 50, 3000, 8000 },
- { 65536, 2048, 16, 4096, 7, 7, 6, 4, 170, 420, 48, 60, 2000, 5000 },
- { 65536, 2048, 16, 4096, 8, 8, 7, 5, 180, 450, 64, 70, 1000, 2500 },
- { 65536, 2048, 32, 8192, 9, 9, 8, 6, 190, 475, 64, 75, 500, 1200 },
- { 65536, 2048, 32, 8192, 9, 9, 9, 6, 200, 500, 96, 80, 200, 500 }
-};
-
-
-static int tight_send_framebuffer_update(VncState *vs, int x, int y,
- int w, int h);
-
-#ifdef CONFIG_VNC_JPEG
-static const struct {
- double jpeg_freq_min; /* Don't send JPEG if the freq is bellow */
- double jpeg_freq_threshold; /* Always send JPEG if the freq is above */
- int jpeg_idx; /* Allow indexed JPEG */
- int jpeg_full; /* Allow full color JPEG */
-} tight_jpeg_conf[] = {
- { 0, 8, 1, 1 },
- { 0, 8, 1, 1 },
- { 0, 8, 1, 1 },
- { 0, 8, 1, 1 },
- { 0, 10, 1, 1 },
- { 0.1, 10, 1, 1 },
- { 0.2, 10, 1, 1 },
- { 0.3, 12, 0, 0 },
- { 0.4, 14, 0, 0 },
- { 0.5, 16, 0, 0 },
-};
-#endif
-
-#ifdef CONFIG_VNC_PNG
-static const struct {
- int png_zlib_level, png_filters;
-} tight_png_conf[] = {
- { 0, PNG_NO_FILTERS },
- { 1, PNG_NO_FILTERS },
- { 2, PNG_NO_FILTERS },
- { 3, PNG_NO_FILTERS },
- { 4, PNG_NO_FILTERS },
- { 5, PNG_ALL_FILTERS },
- { 6, PNG_ALL_FILTERS },
- { 7, PNG_ALL_FILTERS },
- { 8, PNG_ALL_FILTERS },
- { 9, PNG_ALL_FILTERS },
-};
-
-static int send_png_rect(VncState *vs, int x, int y, int w, int h,
- VncPalette *palette);
-
-static bool tight_can_send_png_rect(VncState *vs, int w, int h)
-{
- if (vs->tight.type != VNC_ENCODING_TIGHT_PNG) {
- return false;
- }
-
- if (surface_bytes_per_pixel(vs->vd->ds) == 1 ||
- vs->client_pf.bytes_per_pixel == 1) {
- return false;
- }
-
- return true;
-}
-#endif
-
-/*
- * Code to guess if given rectangle is suitable for smooth image
- * compression (by applying "gradient" filter or JPEG coder).
- */
-
-static unsigned int
-tight_detect_smooth_image24(VncState *vs, int w, int h)
-{
- int off;
- int x, y, d, dx;
- unsigned int c;
- unsigned int stats[256];
- int pixels = 0;
- int pix, left[3];
- unsigned int errors;
- unsigned char *buf = vs->tight.tight.buffer;
-
- /*
- * If client is big-endian, color samples begin from the second
- * byte (offset 1) of a 32-bit pixel value.
- */
- off = vs->client_be;
-
- memset(stats, 0, sizeof (stats));
-
- for (y = 0, x = 0; y < h && x < w;) {
- for (d = 0; d < h - y && d < w - x - VNC_TIGHT_DETECT_SUBROW_WIDTH;
- d++) {
- for (c = 0; c < 3; c++) {
- left[c] = buf[((y+d)*w+x+d)*4+off+c] & 0xFF;
- }
- for (dx = 1; dx <= VNC_TIGHT_DETECT_SUBROW_WIDTH; dx++) {
- for (c = 0; c < 3; c++) {
- pix = buf[((y+d)*w+x+d+dx)*4+off+c] & 0xFF;
- stats[abs(pix - left[c])]++;
- left[c] = pix;
- }
- pixels++;
- }
- }
- if (w > h) {
- x += h;
- y = 0;
- } else {
- x = 0;
- y += w;
- }
- }
-
- if (pixels == 0) {
- return 0;
- }
-
- /* 95% smooth or more ... */
- if (stats[0] * 33 / pixels >= 95) {
- return 0;
- }
-
- errors = 0;
- for (c = 1; c < 8; c++) {
- errors += stats[c] * (c * c);
- if (stats[c] == 0 || stats[c] > stats[c-1] * 2) {
- return 0;
- }
- }
- for (; c < 256; c++) {
- errors += stats[c] * (c * c);
- }
- errors /= (pixels * 3 - stats[0]);
-
- return errors;
-}
-
-#define DEFINE_DETECT_FUNCTION(bpp) \
- \
- static unsigned int \
- tight_detect_smooth_image##bpp(VncState *vs, int w, int h) { \
- bool endian; \
- uint##bpp##_t pix; \
- int max[3], shift[3]; \
- int x, y, d, dx; \
- unsigned int c; \
- unsigned int stats[256]; \
- int pixels = 0; \
- int sample, sum, left[3]; \
- unsigned int errors; \
- unsigned char *buf = vs->tight.tight.buffer; \
- \
- endian = 0; /* FIXME */ \
- \
- \
- max[0] = vs->client_pf.rmax; \
- max[1] = vs->client_pf.gmax; \
- max[2] = vs->client_pf.bmax; \
- shift[0] = vs->client_pf.rshift; \
- shift[1] = vs->client_pf.gshift; \
- shift[2] = vs->client_pf.bshift; \
- \
- memset(stats, 0, sizeof(stats)); \
- \
- y = 0, x = 0; \
- while (y < h && x < w) { \
- for (d = 0; d < h - y && \
- d < w - x - VNC_TIGHT_DETECT_SUBROW_WIDTH; d++) { \
- pix = ((uint##bpp##_t *)buf)[(y+d)*w+x+d]; \
- if (endian) { \
- pix = bswap##bpp(pix); \
- } \
- for (c = 0; c < 3; c++) { \
- left[c] = (int)(pix >> shift[c] & max[c]); \
- } \
- for (dx = 1; dx <= VNC_TIGHT_DETECT_SUBROW_WIDTH; \
- dx++) { \
- pix = ((uint##bpp##_t *)buf)[(y+d)*w+x+d+dx]; \
- if (endian) { \
- pix = bswap##bpp(pix); \
- } \
- sum = 0; \
- for (c = 0; c < 3; c++) { \
- sample = (int)(pix >> shift[c] & max[c]); \
- sum += abs(sample - left[c]); \
- left[c] = sample; \
- } \
- if (sum > 255) { \
- sum = 255; \
- } \
- stats[sum]++; \
- pixels++; \
- } \
- } \
- if (w > h) { \
- x += h; \
- y = 0; \
- } else { \
- x = 0; \
- y += w; \
- } \
- } \
- if (pixels == 0) { \
- return 0; \
- } \
- if ((stats[0] + stats[1]) * 100 / pixels >= 90) { \
- return 0; \
- } \
- \
- errors = 0; \
- for (c = 1; c < 8; c++) { \
- errors += stats[c] * (c * c); \
- if (stats[c] == 0 || stats[c] > stats[c-1] * 2) { \
- return 0; \
- } \
- } \
- for (; c < 256; c++) { \
- errors += stats[c] * (c * c); \
- } \
- errors /= (pixels - stats[0]); \
- \
- return errors; \
- }
-
-DEFINE_DETECT_FUNCTION(16)
-DEFINE_DETECT_FUNCTION(32)
-
-static int
-tight_detect_smooth_image(VncState *vs, int w, int h)
-{
- unsigned int errors;
- int compression = vs->tight.compression;
- int quality = vs->tight.quality;
-
- if (!vs->vd->lossy) {
- return 0;
- }
-
- if (surface_bytes_per_pixel(vs->vd->ds) == 1 ||
- vs->client_pf.bytes_per_pixel == 1 ||
- w < VNC_TIGHT_DETECT_MIN_WIDTH || h < VNC_TIGHT_DETECT_MIN_HEIGHT) {
- return 0;
- }
-
- if (vs->tight.quality != (uint8_t)-1) {
- if (w * h < VNC_TIGHT_JPEG_MIN_RECT_SIZE) {
- return 0;
- }
- } else {
- if (w * h < tight_conf[compression].gradient_min_rect_size) {
- return 0;
- }
- }
-
- if (vs->client_pf.bytes_per_pixel == 4) {
- if (vs->tight.pixel24) {
- errors = tight_detect_smooth_image24(vs, w, h);
- if (vs->tight.quality != (uint8_t)-1) {
- return (errors < tight_conf[quality].jpeg_threshold24);
- }
- return (errors < tight_conf[compression].gradient_threshold24);
- } else {
- errors = tight_detect_smooth_image32(vs, w, h);
- }
- } else {
- errors = tight_detect_smooth_image16(vs, w, h);
- }
- if (quality != (uint8_t)-1) {
- return (errors < tight_conf[quality].jpeg_threshold);
- }
- return (errors < tight_conf[compression].gradient_threshold);
-}
-
-/*
- * Code to determine how many different colors used in rectangle.
- */
-#define DEFINE_FILL_PALETTE_FUNCTION(bpp) \
- \
- static int \
- tight_fill_palette##bpp(VncState *vs, int x, int y, \
- int max, size_t count, \
- uint32_t *bg, uint32_t *fg, \
- VncPalette **palette) { \
- uint##bpp##_t *data; \
- uint##bpp##_t c0, c1, ci; \
- int i, n0, n1; \
- \
- data = (uint##bpp##_t *)vs->tight.tight.buffer; \
- \
- c0 = data[0]; \
- i = 1; \
- while (i < count && data[i] == c0) \
- i++; \
- if (i >= count) { \
- *bg = *fg = c0; \
- return 1; \
- } \
- \
- if (max < 2) { \
- return 0; \
- } \
- \
- n0 = i; \
- c1 = data[i]; \
- n1 = 0; \
- for (i++; i < count; i++) { \
- ci = data[i]; \
- if (ci == c0) { \
- n0++; \
- } else if (ci == c1) { \
- n1++; \
- } else \
- break; \
- } \
- if (i >= count) { \
- if (n0 > n1) { \
- *bg = (uint32_t)c0; \
- *fg = (uint32_t)c1; \
- } else { \
- *bg = (uint32_t)c1; \
- *fg = (uint32_t)c0; \
- } \
- return 2; \
- } \
- \
- if (max == 2) { \
- return 0; \
- } \
- \
- *palette = palette_new(max, bpp); \
- palette_put(*palette, c0); \
- palette_put(*palette, c1); \
- palette_put(*palette, ci); \
- \
- for (i++; i < count; i++) { \
- if (data[i] == ci) { \
- continue; \
- } else { \
- ci = data[i]; \
- if (!palette_put(*palette, (uint32_t)ci)) { \
- return 0; \
- } \
- } \
- } \
- \
- return palette_size(*palette); \
- }
-
-DEFINE_FILL_PALETTE_FUNCTION(8)
-DEFINE_FILL_PALETTE_FUNCTION(16)
-DEFINE_FILL_PALETTE_FUNCTION(32)
-
-static int tight_fill_palette(VncState *vs, int x, int y,
- size_t count, uint32_t *bg, uint32_t *fg,
- VncPalette **palette)
-{
- int max;
-
- max = count / tight_conf[vs->tight.compression].idx_max_colors_divisor;
- if (max < 2 &&
- count >= tight_conf[vs->tight.compression].mono_min_rect_size) {
- max = 2;
- }
- if (max >= 256) {
- max = 256;
- }
-
- switch (vs->client_pf.bytes_per_pixel) {
- case 4:
- return tight_fill_palette32(vs, x, y, max, count, bg, fg, palette);
- case 2:
- return tight_fill_palette16(vs, x, y, max, count, bg, fg, palette);
- default:
- max = 2;
- return tight_fill_palette8(vs, x, y, max, count, bg, fg, palette);
- }
- return 0;
-}
-
-/*
- * Converting truecolor samples into palette indices.
- */
-#define DEFINE_IDX_ENCODE_FUNCTION(bpp) \
- \
- static void \
- tight_encode_indexed_rect##bpp(uint8_t *buf, int count, \
- VncPalette *palette) { \
- uint##bpp##_t *src; \
- uint##bpp##_t rgb; \
- int i, rep; \
- uint8_t idx; \
- \
- src = (uint##bpp##_t *) buf; \
- \
- for (i = 0; i < count; i++) { \
- \
- rgb = *src++; \
- rep = 0; \
- while (i < count && *src == rgb) { \
- rep++, src++, i++; \
- } \
- idx = palette_idx(palette, rgb); \
- /* \
- * Should never happen, but don't break everything \
- * if it does, use the first color instead \
- */ \
- if (idx == (uint8_t)-1) { \
- idx = 0; \
- } \
- while (rep >= 0) { \
- *buf++ = idx; \
- rep--; \
- } \
- } \
- }
-
-DEFINE_IDX_ENCODE_FUNCTION(16)
-DEFINE_IDX_ENCODE_FUNCTION(32)
-
-#define DEFINE_MONO_ENCODE_FUNCTION(bpp) \
- \
- static void \
- tight_encode_mono_rect##bpp(uint8_t *buf, int w, int h, \
- uint##bpp##_t bg, uint##bpp##_t fg) { \
- uint##bpp##_t *ptr; \
- unsigned int value, mask; \
- int aligned_width; \
- int x, y, bg_bits; \
- \
- ptr = (uint##bpp##_t *) buf; \
- aligned_width = w - w % 8; \
- \
- for (y = 0; y < h; y++) { \
- for (x = 0; x < aligned_width; x += 8) { \
- for (bg_bits = 0; bg_bits < 8; bg_bits++) { \
- if (*ptr++ != bg) { \
- break; \
- } \
- } \
- if (bg_bits == 8) { \
- *buf++ = 0; \
- continue; \
- } \
- mask = 0x80 >> bg_bits; \
- value = mask; \
- for (bg_bits++; bg_bits < 8; bg_bits++) { \
- mask >>= 1; \
- if (*ptr++ != bg) { \
- value |= mask; \
- } \
- } \
- *buf++ = (uint8_t)value; \
- } \
- \
- mask = 0x80; \
- value = 0; \
- if (x >= w) { \
- continue; \
- } \
- \
- for (; x < w; x++) { \
- if (*ptr++ != bg) { \
- value |= mask; \
- } \
- mask >>= 1; \
- } \
- *buf++ = (uint8_t)value; \
- } \
- }
-
-DEFINE_MONO_ENCODE_FUNCTION(8)
-DEFINE_MONO_ENCODE_FUNCTION(16)
-DEFINE_MONO_ENCODE_FUNCTION(32)
-
-/*
- * ``Gradient'' filter for 24-bit color samples.
- * Should be called only when redMax, greenMax and blueMax are 255.
- * Color components assumed to be byte-aligned.
- */
-
-static void
-tight_filter_gradient24(VncState *vs, uint8_t *buf, int w, int h)
-{
- uint32_t *buf32;
- uint32_t pix32;
- int shift[3];
- int *prev;
- int here[3], upper[3], left[3], upperleft[3];
- int prediction;
- int x, y, c;
-
- buf32 = (uint32_t *)buf;
- memset(vs->tight.gradient.buffer, 0, w * 3 * sizeof(int));
-
- if (1 /* FIXME */) {
- shift[0] = vs->client_pf.rshift;
- shift[1] = vs->client_pf.gshift;
- shift[2] = vs->client_pf.bshift;
- } else {
- shift[0] = 24 - vs->client_pf.rshift;
- shift[1] = 24 - vs->client_pf.gshift;
- shift[2] = 24 - vs->client_pf.bshift;
- }
-
- for (y = 0; y < h; y++) {
- for (c = 0; c < 3; c++) {
- upper[c] = 0;
- here[c] = 0;
- }
- prev = (int *)vs->tight.gradient.buffer;
- for (x = 0; x < w; x++) {
- pix32 = *buf32++;
- for (c = 0; c < 3; c++) {
- upperleft[c] = upper[c];
- left[c] = here[c];
- upper[c] = *prev;
- here[c] = (int)(pix32 >> shift[c] & 0xFF);
- *prev++ = here[c];
-
- prediction = left[c] + upper[c] - upperleft[c];
- if (prediction < 0) {
- prediction = 0;
- } else if (prediction > 0xFF) {
- prediction = 0xFF;
- }
- *buf++ = (char)(here[c] - prediction);
- }
- }
- }
-}
-
-
-/*
- * ``Gradient'' filter for other color depths.
- */
-
-#define DEFINE_GRADIENT_FILTER_FUNCTION(bpp) \
- \
- static void \
- tight_filter_gradient##bpp(VncState *vs, uint##bpp##_t *buf, \
- int w, int h) { \
- uint##bpp##_t pix, diff; \
- bool endian; \
- int *prev; \
- int max[3], shift[3]; \
- int here[3], upper[3], left[3], upperleft[3]; \
- int prediction; \
- int x, y, c; \
- \
- memset (vs->tight.gradient.buffer, 0, w * 3 * sizeof(int)); \
- \
- endian = 0; /* FIXME */ \
- \
- max[0] = vs->client_pf.rmax; \
- max[1] = vs->client_pf.gmax; \
- max[2] = vs->client_pf.bmax; \
- shift[0] = vs->client_pf.rshift; \
- shift[1] = vs->client_pf.gshift; \
- shift[2] = vs->client_pf.bshift; \
- \
- for (y = 0; y < h; y++) { \
- for (c = 0; c < 3; c++) { \
- upper[c] = 0; \
- here[c] = 0; \
- } \
- prev = (int *)vs->tight.gradient.buffer; \
- for (x = 0; x < w; x++) { \
- pix = *buf; \
- if (endian) { \
- pix = bswap##bpp(pix); \
- } \
- diff = 0; \
- for (c = 0; c < 3; c++) { \
- upperleft[c] = upper[c]; \
- left[c] = here[c]; \
- upper[c] = *prev; \
- here[c] = (int)(pix >> shift[c] & max[c]); \
- *prev++ = here[c]; \
- \
- prediction = left[c] + upper[c] - upperleft[c]; \
- if (prediction < 0) { \
- prediction = 0; \
- } else if (prediction > max[c]) { \
- prediction = max[c]; \
- } \
- diff |= ((here[c] - prediction) & max[c]) \
- << shift[c]; \
- } \
- if (endian) { \
- diff = bswap##bpp(diff); \
- } \
- *buf++ = diff; \
- } \
- } \
- }
-
-DEFINE_GRADIENT_FILTER_FUNCTION(16)
-DEFINE_GRADIENT_FILTER_FUNCTION(32)
-
-/*
- * Check if a rectangle is all of the same color. If needSameColor is
- * set to non-zero, then also check that its color equals to the
- * *colorPtr value. The result is 1 if the test is successful, and in
- * that case new color will be stored in *colorPtr.
- */
-
-static bool
-check_solid_tile32(VncState *vs, int x, int y, int w, int h,
- uint32_t *color, bool samecolor)
-{
- VncDisplay *vd = vs->vd;
- uint32_t *fbptr;
- uint32_t c;
- int dx, dy;
-
- fbptr = vnc_server_fb_ptr(vd, x, y);
-
- c = *fbptr;
- if (samecolor && (uint32_t)c != *color) {
- return false;
- }
-
- for (dy = 0; dy < h; dy++) {
- for (dx = 0; dx < w; dx++) {
- if (c != fbptr[dx]) {
- return false;
- }
- }
- fbptr = (uint32_t *)
- ((uint8_t *)fbptr + vnc_server_fb_stride(vd));
- }
-
- *color = (uint32_t)c;
- return true;
-}
-
-static bool check_solid_tile(VncState *vs, int x, int y, int w, int h,
- uint32_t* color, bool samecolor)
-{
- switch (VNC_SERVER_FB_BYTES) {
- case 4:
- return check_solid_tile32(vs, x, y, w, h, color, samecolor);
- }
-}
-
-static void find_best_solid_area(VncState *vs, int x, int y, int w, int h,
- uint32_t color, int *w_ptr, int *h_ptr)
-{
- int dx, dy, dw, dh;
- int w_prev;
- int w_best = 0, h_best = 0;
-
- w_prev = w;
-
- for (dy = y; dy < y + h; dy += VNC_TIGHT_MAX_SPLIT_TILE_SIZE) {
-
- dh = MIN(VNC_TIGHT_MAX_SPLIT_TILE_SIZE, y + h - dy);
- dw = MIN(VNC_TIGHT_MAX_SPLIT_TILE_SIZE, w_prev);
-
- if (!check_solid_tile(vs, x, dy, dw, dh, &color, true)) {
- break;
- }
-
- for (dx = x + dw; dx < x + w_prev;) {
- dw = MIN(VNC_TIGHT_MAX_SPLIT_TILE_SIZE, x + w_prev - dx);
-
- if (!check_solid_tile(vs, dx, dy, dw, dh, &color, true)) {
- break;
- }
- dx += dw;
- }
-
- w_prev = dx - x;
- if (w_prev * (dy + dh - y) > w_best * h_best) {
- w_best = w_prev;
- h_best = dy + dh - y;
- }
- }
-
- *w_ptr = w_best;
- *h_ptr = h_best;
-}
-
-static void extend_solid_area(VncState *vs, int x, int y, int w, int h,
- uint32_t color, int *x_ptr, int *y_ptr,
- int *w_ptr, int *h_ptr)
-{
- int cx, cy;
-
- /* Try to extend the area upwards. */
- for ( cy = *y_ptr - 1;
- cy >= y && check_solid_tile(vs, *x_ptr, cy, *w_ptr, 1, &color, true);
- cy-- );
- *h_ptr += *y_ptr - (cy + 1);
- *y_ptr = cy + 1;
-
- /* ... downwards. */
- for ( cy = *y_ptr + *h_ptr;
- cy < y + h &&
- check_solid_tile(vs, *x_ptr, cy, *w_ptr, 1, &color, true);
- cy++ );
- *h_ptr += cy - (*y_ptr + *h_ptr);
-
- /* ... to the left. */
- for ( cx = *x_ptr - 1;
- cx >= x && check_solid_tile(vs, cx, *y_ptr, 1, *h_ptr, &color, true);
- cx-- );
- *w_ptr += *x_ptr - (cx + 1);
- *x_ptr = cx + 1;
-
- /* ... to the right. */
- for ( cx = *x_ptr + *w_ptr;
- cx < x + w &&
- check_solid_tile(vs, cx, *y_ptr, 1, *h_ptr, &color, true);
- cx++ );
- *w_ptr += cx - (*x_ptr + *w_ptr);
-}
-
-static int tight_init_stream(VncState *vs, int stream_id,
- int level, int strategy)
-{
- z_streamp zstream = &vs->tight.stream[stream_id];
-
- if (zstream->opaque == NULL) {
- int err;
-
- VNC_DEBUG("VNC: TIGHT: initializing zlib stream %d\n", stream_id);
- VNC_DEBUG("VNC: TIGHT: opaque = %p | vs = %p\n", zstream->opaque, vs);
- zstream->zalloc = vnc_zlib_zalloc;
- zstream->zfree = vnc_zlib_zfree;
-
- err = deflateInit2(zstream, level, Z_DEFLATED, MAX_WBITS,
- MAX_MEM_LEVEL, strategy);
-
- if (err != Z_OK) {
- fprintf(stderr, "VNC: error initializing zlib\n");
- return -1;
- }
-
- vs->tight.levels[stream_id] = level;
- zstream->opaque = vs;
- }
-
- if (vs->tight.levels[stream_id] != level) {
- if (deflateParams(zstream, level, strategy) != Z_OK) {
- return -1;
- }
- vs->tight.levels[stream_id] = level;
- }
- return 0;
-}
-
-static void tight_send_compact_size(VncState *vs, size_t len)
-{
- int lpc = 0;
- int bytes = 0;
- char buf[3] = {0, 0, 0};
-
- buf[bytes++] = len & 0x7F;
- if (len > 0x7F) {
- buf[bytes-1] |= 0x80;
- buf[bytes++] = (len >> 7) & 0x7F;
- if (len > 0x3FFF) {
- buf[bytes-1] |= 0x80;
- buf[bytes++] = (len >> 14) & 0xFF;
- }
- }
- for (lpc = 0; lpc < bytes; lpc++) {
- vnc_write_u8(vs, buf[lpc]);
- }
-}
-
-static int tight_compress_data(VncState *vs, int stream_id, size_t bytes,
- int level, int strategy)
-{
- z_streamp zstream = &vs->tight.stream[stream_id];
- int previous_out;
-
- if (bytes < VNC_TIGHT_MIN_TO_COMPRESS) {
- vnc_write(vs, vs->tight.tight.buffer, vs->tight.tight.offset);
- return bytes;
- }
-
- if (tight_init_stream(vs, stream_id, level, strategy)) {
- return -1;
- }
-
- /* reserve memory in output buffer */
- buffer_reserve(&vs->tight.zlib, bytes + 64);
-
- /* set pointers */
- zstream->next_in = vs->tight.tight.buffer;
- zstream->avail_in = vs->tight.tight.offset;
- zstream->next_out = vs->tight.zlib.buffer + vs->tight.zlib.offset;
- zstream->avail_out = vs->tight.zlib.capacity - vs->tight.zlib.offset;
- previous_out = zstream->avail_out;
- zstream->data_type = Z_BINARY;
-
- /* start encoding */
- if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
- fprintf(stderr, "VNC: error during tight compression\n");
- return -1;
- }
-
- vs->tight.zlib.offset = vs->tight.zlib.capacity - zstream->avail_out;
- /* ...how much data has actually been produced by deflate() */
- bytes = previous_out - zstream->avail_out;
-
- tight_send_compact_size(vs, bytes);
- vnc_write(vs, vs->tight.zlib.buffer, bytes);
-
- buffer_reset(&vs->tight.zlib);
-
- return bytes;
-}
-
-/*
- * Subencoding implementations.
- */
-static void tight_pack24(VncState *vs, uint8_t *buf, size_t count, size_t *ret)
-{
- uint32_t *buf32;
- uint32_t pix;
- int rshift, gshift, bshift;
-
- buf32 = (uint32_t *)buf;
-
- if (1 /* FIXME */) {
- rshift = vs->client_pf.rshift;
- gshift = vs->client_pf.gshift;
- bshift = vs->client_pf.bshift;
- } else {
- rshift = 24 - vs->client_pf.rshift;
- gshift = 24 - vs->client_pf.gshift;
- bshift = 24 - vs->client_pf.bshift;
- }
-
- if (ret) {
- *ret = count * 3;
- }
-
- while (count--) {
- pix = *buf32++;
- *buf++ = (char)(pix >> rshift);
- *buf++ = (char)(pix >> gshift);
- *buf++ = (char)(pix >> bshift);
- }
-}
-
-static int send_full_color_rect(VncState *vs, int x, int y, int w, int h)
-{
- int stream = 0;
- ssize_t bytes;
-
-#ifdef CONFIG_VNC_PNG
- if (tight_can_send_png_rect(vs, w, h)) {
- return send_png_rect(vs, x, y, w, h, NULL);
- }
-#endif
-
- vnc_write_u8(vs, stream << 4); /* no flushing, no filter */
-
- if (vs->tight.pixel24) {
- tight_pack24(vs, vs->tight.tight.buffer, w * h, &vs->tight.tight.offset);
- bytes = 3;
- } else {
- bytes = vs->client_pf.bytes_per_pixel;
- }
-
- bytes = tight_compress_data(vs, stream, w * h * bytes,
- tight_conf[vs->tight.compression].raw_zlib_level,
- Z_DEFAULT_STRATEGY);
-
- return (bytes >= 0);
-}
-
-static int send_solid_rect(VncState *vs)
-{
- size_t bytes;
-
- vnc_write_u8(vs, VNC_TIGHT_FILL << 4); /* no flushing, no filter */
-
- if (vs->tight.pixel24) {
- tight_pack24(vs, vs->tight.tight.buffer, 1, &vs->tight.tight.offset);
- bytes = 3;
- } else {
- bytes = vs->client_pf.bytes_per_pixel;
- }
-
- vnc_write(vs, vs->tight.tight.buffer, bytes);
- return 1;
-}
-
-static int send_mono_rect(VncState *vs, int x, int y,
- int w, int h, uint32_t bg, uint32_t fg)
-{
- ssize_t bytes;
- int stream = 1;
- int level = tight_conf[vs->tight.compression].mono_zlib_level;
-
-#ifdef CONFIG_VNC_PNG
- if (tight_can_send_png_rect(vs, w, h)) {
- int ret;
- int bpp = vs->client_pf.bytes_per_pixel * 8;
- VncPalette *palette = palette_new(2, bpp);
-
- palette_put(palette, bg);
- palette_put(palette, fg);
- ret = send_png_rect(vs, x, y, w, h, palette);
- palette_destroy(palette);
- return ret;
- }
-#endif
-
- bytes = ((w + 7) / 8) * h;
-
- vnc_write_u8(vs, (stream | VNC_TIGHT_EXPLICIT_FILTER) << 4);
- vnc_write_u8(vs, VNC_TIGHT_FILTER_PALETTE);
- vnc_write_u8(vs, 1);
-
- switch (vs->client_pf.bytes_per_pixel) {
- case 4:
- {
- uint32_t buf[2] = {bg, fg};
- size_t ret = sizeof (buf);
-
- if (vs->tight.pixel24) {
- tight_pack24(vs, (unsigned char*)buf, 2, &ret);
- }
- vnc_write(vs, buf, ret);
-
- tight_encode_mono_rect32(vs->tight.tight.buffer, w, h, bg, fg);
- break;
- }
- case 2:
- vnc_write(vs, &bg, 2);
- vnc_write(vs, &fg, 2);
- tight_encode_mono_rect16(vs->tight.tight.buffer, w, h, bg, fg);
- break;
- default:
- vnc_write_u8(vs, bg);
- vnc_write_u8(vs, fg);
- tight_encode_mono_rect8(vs->tight.tight.buffer, w, h, bg, fg);
- break;
- }
- vs->tight.tight.offset = bytes;
-
- bytes = tight_compress_data(vs, stream, bytes, level, Z_DEFAULT_STRATEGY);
- return (bytes >= 0);
-}
-
-struct palette_cb_priv {
- VncState *vs;
- uint8_t *header;
-#ifdef CONFIG_VNC_PNG
- png_colorp png_palette;
-#endif
-};
-
-static void write_palette(int idx, uint32_t color, void *opaque)
-{
- struct palette_cb_priv *priv = opaque;
- VncState *vs = priv->vs;
- uint32_t bytes = vs->client_pf.bytes_per_pixel;
-
- if (bytes == 4) {
- ((uint32_t*)priv->header)[idx] = color;
- } else {
- ((uint16_t*)priv->header)[idx] = color;
- }
-}
-
-static bool send_gradient_rect(VncState *vs, int x, int y, int w, int h)
-{
- int stream = 3;
- int level = tight_conf[vs->tight.compression].gradient_zlib_level;
- ssize_t bytes;
-
- if (vs->client_pf.bytes_per_pixel == 1) {
- return send_full_color_rect(vs, x, y, w, h);
- }
-
- vnc_write_u8(vs, (stream | VNC_TIGHT_EXPLICIT_FILTER) << 4);
- vnc_write_u8(vs, VNC_TIGHT_FILTER_GRADIENT);
-
- buffer_reserve(&vs->tight.gradient, w * 3 * sizeof (int));
-
- if (vs->tight.pixel24) {
- tight_filter_gradient24(vs, vs->tight.tight.buffer, w, h);
- bytes = 3;
- } else if (vs->client_pf.bytes_per_pixel == 4) {
- tight_filter_gradient32(vs, (uint32_t *)vs->tight.tight.buffer, w, h);
- bytes = 4;
- } else {
- tight_filter_gradient16(vs, (uint16_t *)vs->tight.tight.buffer, w, h);
- bytes = 2;
- }
-
- buffer_reset(&vs->tight.gradient);
-
- bytes = w * h * bytes;
- vs->tight.tight.offset = bytes;
-
- bytes = tight_compress_data(vs, stream, bytes,
- level, Z_FILTERED);
- return (bytes >= 0);
-}
-
-static int send_palette_rect(VncState *vs, int x, int y,
- int w, int h, VncPalette *palette)
-{
- int stream = 2;
- int level = tight_conf[vs->tight.compression].idx_zlib_level;
- int colors;
- ssize_t bytes;
-
-#ifdef CONFIG_VNC_PNG
- if (tight_can_send_png_rect(vs, w, h)) {
- return send_png_rect(vs, x, y, w, h, palette);
- }
-#endif
-
- colors = palette_size(palette);
-
- vnc_write_u8(vs, (stream | VNC_TIGHT_EXPLICIT_FILTER) << 4);
- vnc_write_u8(vs, VNC_TIGHT_FILTER_PALETTE);
- vnc_write_u8(vs, colors - 1);
-
- switch (vs->client_pf.bytes_per_pixel) {
- case 4:
- {
- size_t old_offset, offset;
- uint32_t header[palette_size(palette)];
- struct palette_cb_priv priv = { vs, (uint8_t *)header };
-
- old_offset = vs->output.offset;
- palette_iter(palette, write_palette, &priv);
- vnc_write(vs, header, sizeof(header));
-
- if (vs->tight.pixel24) {
- tight_pack24(vs, vs->output.buffer + old_offset, colors, &offset);
- vs->output.offset = old_offset + offset;
- }
-
- tight_encode_indexed_rect32(vs->tight.tight.buffer, w * h, palette);
- break;
- }
- case 2:
- {
- uint16_t header[palette_size(palette)];
- struct palette_cb_priv priv = { vs, (uint8_t *)header };
-
- palette_iter(palette, write_palette, &priv);
- vnc_write(vs, header, sizeof(header));
- tight_encode_indexed_rect16(vs->tight.tight.buffer, w * h, palette);
- break;
- }
- default:
- return -1; /* No palette for 8bits colors */
- break;
- }
- bytes = w * h;
- vs->tight.tight.offset = bytes;
-
- bytes = tight_compress_data(vs, stream, bytes,
- level, Z_DEFAULT_STRATEGY);
- return (bytes >= 0);
-}
-
-/*
- * JPEG compression stuff.
- */
-#ifdef CONFIG_VNC_JPEG
-/*
- * Destination manager implementation for JPEG library.
- */
-
-/* This is called once per encoding */
-static void jpeg_init_destination(j_compress_ptr cinfo)
-{
- VncState *vs = cinfo->client_data;
- Buffer *buffer = &vs->tight.jpeg;
-
- cinfo->dest->next_output_byte = (JOCTET *)buffer->buffer + buffer->offset;
- cinfo->dest->free_in_buffer = (size_t)(buffer->capacity - buffer->offset);
-}
-
-/* This is called when we ran out of buffer (shouldn't happen!) */
-static boolean jpeg_empty_output_buffer(j_compress_ptr cinfo)
-{
- VncState *vs = cinfo->client_data;
- Buffer *buffer = &vs->tight.jpeg;
-
- buffer->offset = buffer->capacity;
- buffer_reserve(buffer, 2048);
- jpeg_init_destination(cinfo);
- return TRUE;
-}
-
-/* This is called when we are done processing data */
-static void jpeg_term_destination(j_compress_ptr cinfo)
-{
- VncState *vs = cinfo->client_data;
- Buffer *buffer = &vs->tight.jpeg;
-
- buffer->offset = buffer->capacity - cinfo->dest->free_in_buffer;
-}
-
-static int send_jpeg_rect(VncState *vs, int x, int y, int w, int h, int quality)
-{
- struct jpeg_compress_struct cinfo;
- struct jpeg_error_mgr jerr;
- struct jpeg_destination_mgr manager;
- pixman_image_t *linebuf;
- JSAMPROW row[1];
- uint8_t *buf;
- int dy;
-
- if (surface_bytes_per_pixel(vs->vd->ds) == 1) {
- return send_full_color_rect(vs, x, y, w, h);
- }
-
- buffer_reserve(&vs->tight.jpeg, 2048);
-
- cinfo.err = jpeg_std_error(&jerr);
- jpeg_create_compress(&cinfo);
-
- cinfo.client_data = vs;
- cinfo.image_width = w;
- cinfo.image_height = h;
- cinfo.input_components = 3;
- cinfo.in_color_space = JCS_RGB;
-
- jpeg_set_defaults(&cinfo);
- jpeg_set_quality(&cinfo, quality, true);
-
- manager.init_destination = jpeg_init_destination;
- manager.empty_output_buffer = jpeg_empty_output_buffer;
- manager.term_destination = jpeg_term_destination;
- cinfo.dest = &manager;
-
- jpeg_start_compress(&cinfo, true);
-
- linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, w);
- buf = (uint8_t *)pixman_image_get_data(linebuf);
- row[0] = buf;
- for (dy = 0; dy < h; dy++) {
- qemu_pixman_linebuf_fill(linebuf, vs->vd->server, w, x, y + dy);
- jpeg_write_scanlines(&cinfo, row, 1);
- }
- qemu_pixman_image_unref(linebuf);
-
- jpeg_finish_compress(&cinfo);
- jpeg_destroy_compress(&cinfo);
-
- vnc_write_u8(vs, VNC_TIGHT_JPEG << 4);
-
- tight_send_compact_size(vs, vs->tight.jpeg.offset);
- vnc_write(vs, vs->tight.jpeg.buffer, vs->tight.jpeg.offset);
- buffer_reset(&vs->tight.jpeg);
-
- return 1;
-}
-#endif /* CONFIG_VNC_JPEG */
-
-/*
- * PNG compression stuff.
- */
-#ifdef CONFIG_VNC_PNG
-static void write_png_palette(int idx, uint32_t pix, void *opaque)
-{
- struct palette_cb_priv *priv = opaque;
- VncState *vs = priv->vs;
- png_colorp color = &priv->png_palette[idx];
-
- if (vs->tight.pixel24)
- {
- color->red = (pix >> vs->client_pf.rshift) & vs->client_pf.rmax;
- color->green = (pix >> vs->client_pf.gshift) & vs->client_pf.gmax;
- color->blue = (pix >> vs->client_pf.bshift) & vs->client_pf.bmax;
- }
- else
- {
- int red, green, blue;
-
- red = (pix >> vs->client_pf.rshift) & vs->client_pf.rmax;
- green = (pix >> vs->client_pf.gshift) & vs->client_pf.gmax;
- blue = (pix >> vs->client_pf.bshift) & vs->client_pf.bmax;
- color->red = ((red * 255 + vs->client_pf.rmax / 2) /
- vs->client_pf.rmax);
- color->green = ((green * 255 + vs->client_pf.gmax / 2) /
- vs->client_pf.gmax);
- color->blue = ((blue * 255 + vs->client_pf.bmax / 2) /
- vs->client_pf.bmax);
- }
-}
-
-static void png_write_data(png_structp png_ptr, png_bytep data,
- png_size_t length)
-{
- VncState *vs = png_get_io_ptr(png_ptr);
-
- buffer_reserve(&vs->tight.png, vs->tight.png.offset + length);
- memcpy(vs->tight.png.buffer + vs->tight.png.offset, data, length);
-
- vs->tight.png.offset += length;
-}
-
-static void png_flush_data(png_structp png_ptr)
-{
-}
-
-static void *vnc_png_malloc(png_structp png_ptr, png_size_t size)
-{
- return g_malloc(size);
-}
-
-static void vnc_png_free(png_structp png_ptr, png_voidp ptr)
-{
- g_free(ptr);
-}
-
-static int send_png_rect(VncState *vs, int x, int y, int w, int h,
- VncPalette *palette)
-{
- png_byte color_type;
- png_structp png_ptr;
- png_infop info_ptr;
- png_colorp png_palette = NULL;
- pixman_image_t *linebuf;
- int level = tight_png_conf[vs->tight.compression].png_zlib_level;
- int filters = tight_png_conf[vs->tight.compression].png_filters;
- uint8_t *buf;
- int dy;
-
- png_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL,
- NULL, vnc_png_malloc, vnc_png_free);
-
- if (png_ptr == NULL)
- return -1;
-
- info_ptr = png_create_info_struct(png_ptr);
-
- if (info_ptr == NULL) {
- png_destroy_write_struct(&png_ptr, NULL);
- return -1;
- }
-
- png_set_write_fn(png_ptr, (void *) vs, png_write_data, png_flush_data);
- png_set_compression_level(png_ptr, level);
- png_set_filter(png_ptr, PNG_FILTER_TYPE_DEFAULT, filters);
-
- if (palette) {
- color_type = PNG_COLOR_TYPE_PALETTE;
- } else {
- color_type = PNG_COLOR_TYPE_RGB;
- }
-
- png_set_IHDR(png_ptr, info_ptr, w, h,
- 8, color_type, PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
-
- if (color_type == PNG_COLOR_TYPE_PALETTE) {
- struct palette_cb_priv priv;
-
- png_palette = png_malloc(png_ptr, sizeof(*png_palette) *
- palette_size(palette));
-
- priv.vs = vs;
- priv.png_palette = png_palette;
- palette_iter(palette, write_png_palette, &priv);
-
- png_set_PLTE(png_ptr, info_ptr, png_palette, palette_size(palette));
-
- if (vs->client_pf.bytes_per_pixel == 4) {
- tight_encode_indexed_rect32(vs->tight.tight.buffer, w * h, palette);
- } else {
- tight_encode_indexed_rect16(vs->tight.tight.buffer, w * h, palette);
- }
- }
-
- png_write_info(png_ptr, info_ptr);
-
- buffer_reserve(&vs->tight.png, 2048);
- linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, w);
- buf = (uint8_t *)pixman_image_get_data(linebuf);
- for (dy = 0; dy < h; dy++)
- {
- if (color_type == PNG_COLOR_TYPE_PALETTE) {
- memcpy(buf, vs->tight.tight.buffer + (dy * w), w);
- } else {
- qemu_pixman_linebuf_fill(linebuf, vs->vd->server, w, x, y + dy);
- }
- png_write_row(png_ptr, buf);
- }
- qemu_pixman_image_unref(linebuf);
-
- png_write_end(png_ptr, NULL);
-
- if (color_type == PNG_COLOR_TYPE_PALETTE) {
- png_free(png_ptr, png_palette);
- }
-
- png_destroy_write_struct(&png_ptr, &info_ptr);
-
- vnc_write_u8(vs, VNC_TIGHT_PNG << 4);
-
- tight_send_compact_size(vs, vs->tight.png.offset);
- vnc_write(vs, vs->tight.png.buffer, vs->tight.png.offset);
- buffer_reset(&vs->tight.png);
- return 1;
-}
-#endif /* CONFIG_VNC_PNG */
-
-static void vnc_tight_start(VncState *vs)
-{
- buffer_reset(&vs->tight.tight);
-
- // make the output buffer be the zlib buffer, so we can compress it later
- vs->tight.tmp = vs->output;
- vs->output = vs->tight.tight;
-}
-
-static void vnc_tight_stop(VncState *vs)
-{
- // switch back to normal output/zlib buffers
- vs->tight.tight = vs->output;
- vs->output = vs->tight.tmp;
-}
-
-static int send_sub_rect_nojpeg(VncState *vs, int x, int y, int w, int h,
- int bg, int fg, int colors, VncPalette *palette)
-{
- int ret;
-
- if (colors == 0) {
- if (tight_detect_smooth_image(vs, w, h)) {
- ret = send_gradient_rect(vs, x, y, w, h);
- } else {
- ret = send_full_color_rect(vs, x, y, w, h);
- }
- } else if (colors == 1) {
- ret = send_solid_rect(vs);
- } else if (colors == 2) {
- ret = send_mono_rect(vs, x, y, w, h, bg, fg);
- } else if (colors <= 256) {
- ret = send_palette_rect(vs, x, y, w, h, palette);
- } else {
- ret = 0;
- }
- return ret;
-}
-
-#ifdef CONFIG_VNC_JPEG
-static int send_sub_rect_jpeg(VncState *vs, int x, int y, int w, int h,
- int bg, int fg, int colors,
- VncPalette *palette, bool force)
-{
- int ret;
-
- if (colors == 0) {
- if (force || (tight_jpeg_conf[vs->tight.quality].jpeg_full &&
- tight_detect_smooth_image(vs, w, h))) {
- int quality = tight_conf[vs->tight.quality].jpeg_quality;
-
- ret = send_jpeg_rect(vs, x, y, w, h, quality);
- } else {
- ret = send_full_color_rect(vs, x, y, w, h);
- }
- } else if (colors == 1) {
- ret = send_solid_rect(vs);
- } else if (colors == 2) {
- ret = send_mono_rect(vs, x, y, w, h, bg, fg);
- } else if (colors <= 256) {
- if (force || (colors > 96 &&
- tight_jpeg_conf[vs->tight.quality].jpeg_idx &&
- tight_detect_smooth_image(vs, w, h))) {
- int quality = tight_conf[vs->tight.quality].jpeg_quality;
-
- ret = send_jpeg_rect(vs, x, y, w, h, quality);
- } else {
- ret = send_palette_rect(vs, x, y, w, h, palette);
- }
- } else {
- ret = 0;
- }
- return ret;
-}
-#endif
-
-static int send_sub_rect(VncState *vs, int x, int y, int w, int h)
-{
- VncPalette *palette = NULL;
- uint32_t bg = 0, fg = 0;
- int colors;
- int ret = 0;
-#ifdef CONFIG_VNC_JPEG
- bool force_jpeg = false;
- bool allow_jpeg = true;
-#endif
-
- vnc_framebuffer_update(vs, x, y, w, h, vs->tight.type);
-
- vnc_tight_start(vs);
- vnc_raw_send_framebuffer_update(vs, x, y, w, h);
- vnc_tight_stop(vs);
-
-#ifdef CONFIG_VNC_JPEG
- if (!vs->vd->non_adaptive && vs->tight.quality != (uint8_t)-1) {
- double freq = vnc_update_freq(vs, x, y, w, h);
-
- if (freq < tight_jpeg_conf[vs->tight.quality].jpeg_freq_min) {
- allow_jpeg = false;
- }
- if (freq >= tight_jpeg_conf[vs->tight.quality].jpeg_freq_threshold) {
- force_jpeg = true;
- vnc_sent_lossy_rect(vs, x, y, w, h);
- }
- }
-#endif
-
- colors = tight_fill_palette(vs, x, y, w * h, &bg, &fg, &palette);
-
-#ifdef CONFIG_VNC_JPEG
- if (allow_jpeg && vs->tight.quality != (uint8_t)-1) {
- ret = send_sub_rect_jpeg(vs, x, y, w, h, bg, fg, colors, palette,
- force_jpeg);
- } else {
- ret = send_sub_rect_nojpeg(vs, x, y, w, h, bg, fg, colors, palette);
- }
-#else
- ret = send_sub_rect_nojpeg(vs, x, y, w, h, bg, fg, colors, palette);
-#endif
-
- palette_destroy(palette);
- return ret;
-}
-
-static int send_sub_rect_solid(VncState *vs, int x, int y, int w, int h)
-{
- vnc_framebuffer_update(vs, x, y, w, h, vs->tight.type);
-
- vnc_tight_start(vs);
- vnc_raw_send_framebuffer_update(vs, x, y, w, h);
- vnc_tight_stop(vs);
-
- return send_solid_rect(vs);
-}
-
-static int send_rect_simple(VncState *vs, int x, int y, int w, int h,
- bool split)
-{
- int max_size, max_width;
- int max_sub_width, max_sub_height;
- int dx, dy;
- int rw, rh;
- int n = 0;
-
- max_size = tight_conf[vs->tight.compression].max_rect_size;
- max_width = tight_conf[vs->tight.compression].max_rect_width;
-
- if (split && (w > max_width || w * h > max_size)) {
- max_sub_width = (w > max_width) ? max_width : w;
- max_sub_height = max_size / max_sub_width;
-
- for (dy = 0; dy < h; dy += max_sub_height) {
- for (dx = 0; dx < w; dx += max_width) {
- rw = MIN(max_sub_width, w - dx);
- rh = MIN(max_sub_height, h - dy);
- n += send_sub_rect(vs, x+dx, y+dy, rw, rh);
- }
- }
- } else {
- n += send_sub_rect(vs, x, y, w, h);
- }
-
- return n;
-}
-
-static int find_large_solid_color_rect(VncState *vs, int x, int y,
- int w, int h, int max_rows)
-{
- int dx, dy, dw, dh;
- int n = 0;
-
- /* Try to find large solid-color areas and send them separately. */
-
- for (dy = y; dy < y + h; dy += VNC_TIGHT_MAX_SPLIT_TILE_SIZE) {
-
- /* If a rectangle becomes too large, send its upper part now. */
-
- if (dy - y >= max_rows) {
- n += send_rect_simple(vs, x, y, w, max_rows, true);
- y += max_rows;
- h -= max_rows;
- }
-
- dh = MIN(VNC_TIGHT_MAX_SPLIT_TILE_SIZE, (y + h - dy));
-
- for (dx = x; dx < x + w; dx += VNC_TIGHT_MAX_SPLIT_TILE_SIZE) {
- uint32_t color_value;
- int x_best, y_best, w_best, h_best;
-
- dw = MIN(VNC_TIGHT_MAX_SPLIT_TILE_SIZE, (x + w - dx));
-
- if (!check_solid_tile(vs, dx, dy, dw, dh, &color_value, false)) {
- continue ;
- }
-
- /* Get dimensions of solid-color area. */
-
- find_best_solid_area(vs, dx, dy, w - (dx - x), h - (dy - y),
- color_value, &w_best, &h_best);
-
- /* Make sure a solid rectangle is large enough
- (or the whole rectangle is of the same color). */
-
- if (w_best * h_best != w * h &&
- w_best * h_best < VNC_TIGHT_MIN_SOLID_SUBRECT_SIZE) {
- continue;
- }
-
- /* Try to extend solid rectangle to maximum size. */
-
- x_best = dx; y_best = dy;
- extend_solid_area(vs, x, y, w, h, color_value,
- &x_best, &y_best, &w_best, &h_best);
-
- /* Send rectangles at top and left to solid-color area. */
-
- if (y_best != y) {
- n += send_rect_simple(vs, x, y, w, y_best-y, true);
- }
- if (x_best != x) {
- n += tight_send_framebuffer_update(vs, x, y_best,
- x_best-x, h_best);
- }
-
- /* Send solid-color rectangle. */
- n += send_sub_rect_solid(vs, x_best, y_best, w_best, h_best);
-
- /* Send remaining rectangles (at right and bottom). */
-
- if (x_best + w_best != x + w) {
- n += tight_send_framebuffer_update(vs, x_best+w_best,
- y_best,
- w-(x_best-x)-w_best,
- h_best);
- }
- if (y_best + h_best != y + h) {
- n += tight_send_framebuffer_update(vs, x, y_best+h_best,
- w, h-(y_best-y)-h_best);
- }
-
- /* Return after all recursive calls are done. */
- return n;
- }
- }
- return n + send_rect_simple(vs, x, y, w, h, true);
-}
-
-static int tight_send_framebuffer_update(VncState *vs, int x, int y,
- int w, int h)
-{
- int max_rows;
-
- if (vs->client_pf.bytes_per_pixel == 4 && vs->client_pf.rmax == 0xFF &&
- vs->client_pf.bmax == 0xFF && vs->client_pf.gmax == 0xFF) {
- vs->tight.pixel24 = true;
- } else {
- vs->tight.pixel24 = false;
- }
-
-#ifdef CONFIG_VNC_JPEG
- if (vs->tight.quality != (uint8_t)-1) {
- double freq = vnc_update_freq(vs, x, y, w, h);
-
- if (freq > tight_jpeg_conf[vs->tight.quality].jpeg_freq_threshold) {
- return send_rect_simple(vs, x, y, w, h, false);
- }
- }
-#endif
-
- if (w * h < VNC_TIGHT_MIN_SPLIT_RECT_SIZE) {
- return send_rect_simple(vs, x, y, w, h, true);
- }
-
- /* Calculate maximum number of rows in one non-solid rectangle. */
-
- max_rows = tight_conf[vs->tight.compression].max_rect_size;
- max_rows /= MIN(tight_conf[vs->tight.compression].max_rect_width, w);
-
- return find_large_solid_color_rect(vs, x, y, w, h, max_rows);
-}
-
-int vnc_tight_send_framebuffer_update(VncState *vs, int x, int y,
- int w, int h)
-{
- vs->tight.type = VNC_ENCODING_TIGHT;
- return tight_send_framebuffer_update(vs, x, y, w, h);
-}
-
-int vnc_tight_png_send_framebuffer_update(VncState *vs, int x, int y,
- int w, int h)
-{
- vs->tight.type = VNC_ENCODING_TIGHT_PNG;
- return tight_send_framebuffer_update(vs, x, y, w, h);
-}
-
-void vnc_tight_clear(VncState *vs)
-{
- int i;
- for (i=0; i<ARRAY_SIZE(vs->tight.stream); i++) {
- if (vs->tight.stream[i].opaque) {
- deflateEnd(&vs->tight.stream[i]);
- }
- }
-
- buffer_free(&vs->tight.tight);
- buffer_free(&vs->tight.zlib);
- buffer_free(&vs->tight.gradient);
-#ifdef CONFIG_VNC_JPEG
- buffer_free(&vs->tight.jpeg);
-#endif
-#ifdef CONFIG_VNC_PNG
- buffer_free(&vs->tight.png);
-#endif
-}
diff --git a/qemu/ui/vnc-enc-tight.h b/qemu/ui/vnc-enc-tight.h
deleted file mode 100644
index a3add788e..000000000
--- a/qemu/ui/vnc-enc-tight.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * QEMU VNC display driver: tight encoding
- *
- * From libvncserver/rfb/rfbproto.h
- * Copyright (C) 2005 Rohit Kumar, Johannes E. Schindelin
- * Copyright (C) 2000-2002 Constantin Kaplinsky. All Rights Reserved.
- * Copyright (C) 2000 Tridia Corporation. All Rights Reserved.
- * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
- *
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef VNC_ENCODING_TIGHT_H
-#define VNC_ENCODING_TIGHT_H
-
-/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * Tight Encoding.
- *
- *-- The first byte of each Tight-encoded rectangle is a "compression control
- * byte". Its format is as follows (bit 0 is the least significant one):
- *
- * bit 0: if 1, then compression stream 0 should be reset;
- * bit 1: if 1, then compression stream 1 should be reset;
- * bit 2: if 1, then compression stream 2 should be reset;
- * bit 3: if 1, then compression stream 3 should be reset;
- * bits 7-4: if 1000 (0x08), then the compression type is "fill",
- * if 1001 (0x09), then the compression type is "jpeg",
- * if 1010 (0x0A), then the compression type is "png",
- * if 0xxx, then the compression type is "basic",
- * values greater than 1010 are not valid.
- *
- * If the compression type is "basic", then bits 6..4 of the
- * compression control byte (those xxx in 0xxx) specify the following:
- *
- * bits 5-4: decimal representation is the index of a particular zlib
- * stream which should be used for decompressing the data;
- * bit 6: if 1, then a "filter id" byte is following this byte.
- *
- *-- The data that follows after the compression control byte described
- * above depends on the compression type ("fill", "jpeg", "png" or "basic").
- *
- *-- If the compression type is "fill", then the only pixel value follows, in
- * client pixel format (see NOTE 1). This value applies to all pixels of the
- * rectangle.
- *
- *-- If the compression type is "jpeg" or "png", the following data stream
- * looks like this:
- *
- * 1..3 bytes: data size (N) in compact representation;
- * N bytes: JPEG or PNG image.
- *
- * Data size is compactly represented in one, two or three bytes, according
- * to the following scheme:
- *
- * 0xxxxxxx (for values 0..127)
- * 1xxxxxxx 0yyyyyyy (for values 128..16383)
- * 1xxxxxxx 1yyyyyyy zzzzzzzz (for values 16384..4194303)
- *
- * Here each character denotes one bit, xxxxxxx are the least significant 7
- * bits of the value (bits 0-6), yyyyyyy are bits 7-13, and zzzzzzzz are the
- * most significant 8 bits (bits 14-21). For example, decimal value 10000
- * should be represented as two bytes: binary 10010000 01001110, or
- * hexadecimal 90 4E.
- *
- *-- If the compression type is "basic" and bit 6 of the compression control
- * byte was set to 1, then the next (second) byte specifies "filter id" which
- * tells the decoder what filter type was used by the encoder to pre-process
- * pixel data before the compression. The "filter id" byte can be one of the
- * following:
- *
- * 0: no filter ("copy" filter);
- * 1: "palette" filter;
- * 2: "gradient" filter.
- *
- *-- If bit 6 of the compression control byte is set to 0 (no "filter id"
- * byte), or if the filter id is 0, then raw pixel values in the client
- * format (see NOTE 1) will be compressed. See below details on the
- * compression.
- *
- *-- The "gradient" filter pre-processes pixel data with a simple algorithm
- * which converts each color component to a difference between a "predicted"
- * intensity and the actual intensity. Such a technique does not affect
- * uncompressed data size, but helps to compress photo-like images better.
- * Pseudo-code for converting intensities to differences is the following:
- *
- * P[i,j] := V[i-1,j] + V[i,j-1] - V[i-1,j-1];
- * if (P[i,j] < 0) then P[i,j] := 0;
- * if (P[i,j] > MAX) then P[i,j] := MAX;
- * D[i,j] := V[i,j] - P[i,j];
- *
- * Here V[i,j] is the intensity of a color component for a pixel at
- * coordinates (i,j). MAX is the maximum value of intensity for a color
- * component.
- *
- *-- The "palette" filter converts true-color pixel data to indexed colors
- * and a palette which can consist of 2..256 colors. If the number of colors
- * is 2, then each pixel is encoded in 1 bit, otherwise 8 bits is used to
- * encode one pixel. 1-bit encoding is performed such way that the most
- * significant bits correspond to the leftmost pixels, and each raw of pixels
- * is aligned to the byte boundary. When "palette" filter is used, the
- * palette is sent before the pixel data. The palette begins with an unsigned
- * byte which value is the number of colors in the palette minus 1 (i.e. 1
- * means 2 colors, 255 means 256 colors in the palette). Then follows the
- * palette itself which consist of pixel values in client pixel format (see
- * NOTE 1).
- *
- *-- The pixel data is compressed using the zlib library. But if the data
- * size after applying the filter but before the compression is less then 12,
- * then the data is sent as is, uncompressed. Four separate zlib streams
- * (0..3) can be used and the decoder should read the actual stream id from
- * the compression control byte (see NOTE 2).
- *
- * If the compression is not used, then the pixel data is sent as is,
- * otherwise the data stream looks like this:
- *
- * 1..3 bytes: data size (N) in compact representation;
- * N bytes: zlib-compressed data.
- *
- * Data size is compactly represented in one, two or three bytes, just like
- * in the "jpeg" compression method (see above).
- *
- *-- NOTE 1. If the color depth is 24, and all three color components are
- * 8-bit wide, then one pixel in Tight encoding is always represented by
- * three bytes, where the first byte is red component, the second byte is
- * green component, and the third byte is blue component of the pixel color
- * value. This applies to colors in palettes as well.
- *
- *-- NOTE 2. The decoder must reset compression streams' states before
- * decoding the rectangle, if some of bits 0,1,2,3 in the compression control
- * byte are set to 1. Note that the decoder must reset zlib streams even if
- * the compression type is "fill", "jpeg" or "png".
- *
- *-- NOTE 3. The "gradient" filter and "jpeg" compression may be used only
- * when bits-per-pixel value is either 16 or 32, not 8.
- *
- *-- NOTE 4. The width of any Tight-encoded rectangle cannot exceed 2048
- * pixels. If a rectangle is wider, it must be split into several rectangles
- * and each one should be encoded separately.
- *
- */
-
-#define VNC_TIGHT_EXPLICIT_FILTER 0x04
-#define VNC_TIGHT_FILL 0x08
-#define VNC_TIGHT_JPEG 0x09
-#define VNC_TIGHT_PNG 0x0A
-#define VNC_TIGHT_MAX_SUBENCODING 0x0A
-
-/* Filters to improve compression efficiency */
-#define VNC_TIGHT_FILTER_COPY 0x00
-#define VNC_TIGHT_FILTER_PALETTE 0x01
-#define VNC_TIGHT_FILTER_GRADIENT 0x02
-
-/* Note: The following constant should not be changed. */
-#define VNC_TIGHT_MIN_TO_COMPRESS 12
-
-/* The parameters below may be adjusted. */
-#define VNC_TIGHT_MIN_SPLIT_RECT_SIZE 4096
-#define VNC_TIGHT_MIN_SOLID_SUBRECT_SIZE 2048
-#define VNC_TIGHT_MAX_SPLIT_TILE_SIZE 16
-
-#define VNC_TIGHT_JPEG_MIN_RECT_SIZE 4096
-#define VNC_TIGHT_DETECT_SUBROW_WIDTH 7
-#define VNC_TIGHT_DETECT_MIN_WIDTH 8
-#define VNC_TIGHT_DETECT_MIN_HEIGHT 8
-
-#endif /* VNC_ENCODING_TIGHT_H */
diff --git a/qemu/ui/vnc-enc-zlib.c b/qemu/ui/vnc-enc-zlib.c
deleted file mode 100644
index 33e9df2f6..000000000
--- a/qemu/ui/vnc-enc-zlib.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * QEMU VNC display driver: zlib encoding
- *
- * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
- * Copyright (C) 2006 Fabrice Bellard
- * Copyright (C) 2009 Red Hat, Inc
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "vnc.h"
-
-#define ZALLOC_ALIGNMENT 16
-
-void *vnc_zlib_zalloc(void *x, unsigned items, unsigned size)
-{
- void *p;
-
- size *= items;
- size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
-
- p = g_malloc0(size);
-
- return (p);
-}
-
-void vnc_zlib_zfree(void *x, void *addr)
-{
- g_free(addr);
-}
-
-static void vnc_zlib_start(VncState *vs)
-{
- buffer_reset(&vs->zlib.zlib);
-
- // make the output buffer be the zlib buffer, so we can compress it later
- vs->zlib.tmp = vs->output;
- vs->output = vs->zlib.zlib;
-}
-
-static int vnc_zlib_stop(VncState *vs)
-{
- z_streamp zstream = &vs->zlib.stream;
- int previous_out;
-
- // switch back to normal output/zlib buffers
- vs->zlib.zlib = vs->output;
- vs->output = vs->zlib.tmp;
-
- // compress the zlib buffer
-
- // initialize the stream
- // XXX need one stream per session
- if (zstream->opaque != vs) {
- int err;
-
- VNC_DEBUG("VNC: initializing zlib stream\n");
- VNC_DEBUG("VNC: opaque = %p | vs = %p\n", zstream->opaque, vs);
- zstream->zalloc = vnc_zlib_zalloc;
- zstream->zfree = vnc_zlib_zfree;
-
- err = deflateInit2(zstream, vs->tight.compression, Z_DEFLATED, MAX_WBITS,
- MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
-
- if (err != Z_OK) {
- fprintf(stderr, "VNC: error initializing zlib\n");
- return -1;
- }
-
- vs->zlib.level = vs->tight.compression;
- zstream->opaque = vs;
- }
-
- if (vs->tight.compression != vs->zlib.level) {
- if (deflateParams(zstream, vs->tight.compression,
- Z_DEFAULT_STRATEGY) != Z_OK) {
- return -1;
- }
- vs->zlib.level = vs->tight.compression;
- }
-
- // reserve memory in output buffer
- buffer_reserve(&vs->output, vs->zlib.zlib.offset + 64);
-
- // set pointers
- zstream->next_in = vs->zlib.zlib.buffer;
- zstream->avail_in = vs->zlib.zlib.offset;
- zstream->next_out = vs->output.buffer + vs->output.offset;
- zstream->avail_out = vs->output.capacity - vs->output.offset;
- previous_out = zstream->avail_out;
- zstream->data_type = Z_BINARY;
-
- // start encoding
- if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
- fprintf(stderr, "VNC: error during zlib compression\n");
- return -1;
- }
-
- vs->output.offset = vs->output.capacity - zstream->avail_out;
- return previous_out - zstream->avail_out;
-}
-
-int vnc_zlib_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
-{
- int old_offset, new_offset, bytes_written;
-
- vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_ZLIB);
-
- // remember where we put in the follow-up size
- old_offset = vs->output.offset;
- vnc_write_s32(vs, 0);
-
- // compress the stream
- vnc_zlib_start(vs);
- vnc_raw_send_framebuffer_update(vs, x, y, w, h);
- bytes_written = vnc_zlib_stop(vs);
-
- if (bytes_written == -1)
- return 0;
-
- // hack in the size
- new_offset = vs->output.offset;
- vs->output.offset = old_offset;
- vnc_write_u32(vs, bytes_written);
- vs->output.offset = new_offset;
-
- return 1;
-}
-
-void vnc_zlib_clear(VncState *vs)
-{
- if (vs->zlib.stream.opaque) {
- deflateEnd(&vs->zlib.stream);
- }
- buffer_free(&vs->zlib.zlib);
-}
diff --git a/qemu/ui/vnc-enc-zrle-template.c b/qemu/ui/vnc-enc-zrle-template.c
deleted file mode 100644
index abf6b86e4..000000000
--- a/qemu/ui/vnc-enc-zrle-template.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * QEMU VNC display driver: Zlib Run-length Encoding (ZRLE)
- *
- * From libvncserver/libvncserver/zrleencodetemplate.c
- * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
- * Copyright (C) 2003 Sun Microsystems, Inc.
- *
- * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-/*
- * Before including this file, you must define a number of CPP macros.
- *
- * ZRLE_BPP should be 8, 16 or 32 depending on the bits per pixel.
- *
- * Note that the buf argument to ZRLE_ENCODE needs to be at least one pixel
- * bigger than the largest tile of pixel data, since the ZRLE encoding
- * algorithm writes to the position one past the end of the pixel data.
- */
-
-
-#include "qemu/osdep.h"
-
-#undef ZRLE_ENDIAN_SUFFIX
-
-#if ZYWRLE_ENDIAN == ENDIAN_LITTLE
-#define ZRLE_ENDIAN_SUFFIX le
-#elif ZYWRLE_ENDIAN == ENDIAN_BIG
-#define ZRLE_ENDIAN_SUFFIX be
-#else
-#define ZRLE_ENDIAN_SUFFIX ne
-#endif
-
-#ifndef ZRLE_CONCAT
-#define ZRLE_CONCAT_I(a, b) a##b
-#define ZRLE_CONCAT2(a, b) ZRLE_CONCAT_I(a, b)
-#define ZRLE_CONCAT3(a, b, c) ZRLE_CONCAT2(a, ZRLE_CONCAT2(b, c))
-#endif
-
-#ifdef ZRLE_COMPACT_PIXEL
-#define ZRLE_ENCODE_SUFFIX ZRLE_CONCAT2(ZRLE_COMPACT_PIXEL,ZRLE_ENDIAN_SUFFIX)
-#define ZRLE_WRITE_SUFFIX ZRLE_COMPACT_PIXEL
-#define ZRLE_PIXEL ZRLE_CONCAT3(uint,ZRLE_BPP,_t)
-#define ZRLE_BPP_OUT 24
-#elif ZRLE_BPP == 15
-#define ZRLE_ENCODE_SUFFIX ZRLE_CONCAT2(ZRLE_BPP,ZRLE_ENDIAN_SUFFIX)
-#define ZRLE_WRITE_SUFFIX 16
-#define ZRLE_PIXEL uint16_t
-#define ZRLE_BPP_OUT 16
-#else
-#define ZRLE_ENCODE_SUFFIX ZRLE_CONCAT2(ZRLE_BPP,ZRLE_ENDIAN_SUFFIX)
-#define ZRLE_WRITE_SUFFIX ZRLE_BPP
-#define ZRLE_BPP_OUT ZRLE_BPP
-#define ZRLE_PIXEL ZRLE_CONCAT3(uint,ZRLE_BPP,_t)
-#endif
-
-#define ZRLE_WRITE_PIXEL ZRLE_CONCAT2(zrle_write_u, ZRLE_WRITE_SUFFIX)
-#define ZRLE_ENCODE ZRLE_CONCAT2(zrle_encode_, ZRLE_ENCODE_SUFFIX)
-#define ZRLE_ENCODE_TILE ZRLE_CONCAT2(zrle_encode_tile, ZRLE_ENCODE_SUFFIX)
-#define ZRLE_WRITE_PALETTE ZRLE_CONCAT2(zrle_write_palette,ZRLE_ENCODE_SUFFIX)
-
-static void ZRLE_ENCODE_TILE(VncState *vs, ZRLE_PIXEL *data, int w, int h,
- int zywrle_level);
-
-#if ZRLE_BPP != 8
-#include "vnc-enc-zywrle-template.c"
-#endif
-
-
-static void ZRLE_ENCODE(VncState *vs, int x, int y, int w, int h,
- int zywrle_level)
-{
- int ty;
-
- for (ty = y; ty < y + h; ty += VNC_ZRLE_TILE_HEIGHT) {
-
- int tx, th;
-
- th = MIN(VNC_ZRLE_TILE_HEIGHT, y + h - ty);
-
- for (tx = x; tx < x + w; tx += VNC_ZRLE_TILE_WIDTH) {
- int tw;
- ZRLE_PIXEL *buf;
-
- tw = MIN(VNC_ZRLE_TILE_WIDTH, x + w - tx);
-
- buf = zrle_convert_fb(vs, tx, ty, tw, th, ZRLE_BPP);
- ZRLE_ENCODE_TILE(vs, buf, tw, th, zywrle_level);
- }
- }
-}
-
-static void ZRLE_ENCODE_TILE(VncState *vs, ZRLE_PIXEL *data, int w, int h,
- int zywrle_level)
-{
- VncPalette *palette = &vs->zrle.palette;
-
- int runs = 0;
- int single_pixels = 0;
-
- bool use_rle;
- bool use_palette;
-
- int i;
-
- ZRLE_PIXEL *ptr = data;
- ZRLE_PIXEL *end = ptr + h * w;
- *end = ~*(end-1); /* one past the end is different so the while loop ends */
-
- /* Real limit is 127 but we wan't a way to know if there is more than 127 */
- palette_init(palette, 256, ZRLE_BPP);
-
- while (ptr < end) {
- ZRLE_PIXEL pix = *ptr;
- if (*++ptr != pix) { /* FIXME */
- single_pixels++;
- } else {
- while (*++ptr == pix) ;
- runs++;
- }
- palette_put(palette, pix);
- }
-
- /* Solid tile is a special case */
-
- if (palette_size(palette) == 1) {
- bool found;
-
- vnc_write_u8(vs, 1);
- ZRLE_WRITE_PIXEL(vs, palette_color(palette, 0, &found));
- return;
- }
-
- zrle_choose_palette_rle(vs, w, h, palette, ZRLE_BPP_OUT,
- runs, single_pixels, zywrle_level,
- &use_rle, &use_palette);
-
- if (!use_palette) {
- vnc_write_u8(vs, (use_rle ? 128 : 0));
- } else {
- uint32_t colors[VNC_PALETTE_MAX_SIZE];
- size_t size = palette_size(palette);
-
- vnc_write_u8(vs, (use_rle ? 128 : 0) | size);
- palette_fill(palette, colors);
-
- for (i = 0; i < size; i++) {
- ZRLE_WRITE_PIXEL(vs, colors[i]);
- }
- }
-
- if (use_rle) {
- ZRLE_PIXEL *ptr = data;
- ZRLE_PIXEL *end = ptr + w * h;
- ZRLE_PIXEL *run_start;
- ZRLE_PIXEL pix;
-
- while (ptr < end) {
- int len;
- int index = 0;
-
- run_start = ptr;
- pix = *ptr++;
-
- while (*ptr == pix && ptr < end) {
- ptr++;
- }
-
- len = ptr - run_start;
-
- if (use_palette)
- index = palette_idx(palette, pix);
-
- if (len <= 2 && use_palette) {
- if (len == 2) {
- vnc_write_u8(vs, index);
- }
- vnc_write_u8(vs, index);
- continue;
- }
- if (use_palette) {
- vnc_write_u8(vs, index | 128);
- } else {
- ZRLE_WRITE_PIXEL(vs, pix);
- }
-
- len -= 1;
-
- while (len >= 255) {
- vnc_write_u8(vs, 255);
- len -= 255;
- }
-
- vnc_write_u8(vs, len);
- }
- } else if (use_palette) { /* no RLE */
- int bppp;
- ZRLE_PIXEL *ptr = data;
-
- /* packed pixels */
-
- assert (palette_size(palette) < 17);
-
- bppp = bits_per_packed_pixel[palette_size(palette)-1];
-
- for (i = 0; i < h; i++) {
- uint8_t nbits = 0;
- uint8_t byte = 0;
-
- ZRLE_PIXEL *eol = ptr + w;
-
- while (ptr < eol) {
- ZRLE_PIXEL pix = *ptr++;
- uint8_t index = palette_idx(palette, pix);
-
- byte = (byte << bppp) | index;
- nbits += bppp;
- if (nbits >= 8) {
- vnc_write_u8(vs, byte);
- nbits = 0;
- }
- }
- if (nbits > 0) {
- byte <<= 8 - nbits;
- vnc_write_u8(vs, byte);
- }
- }
- } else {
-
- /* raw */
-
-#if ZRLE_BPP != 8
- if (zywrle_level > 0 && !(zywrle_level & 0x80)) {
- ZYWRLE_ANALYZE(data, data, w, h, w, zywrle_level, vs->zywrle.buf);
- ZRLE_ENCODE_TILE(vs, data, w, h, zywrle_level | 0x80);
- }
- else
-#endif
- {
-#ifdef ZRLE_COMPACT_PIXEL
- ZRLE_PIXEL *ptr;
-
- for (ptr = data; ptr < data + w * h; ptr++) {
- ZRLE_WRITE_PIXEL(vs, *ptr);
- }
-#else
- vnc_write(vs, data, w * h * (ZRLE_BPP / 8));
-#endif
- }
- }
-}
-
-#undef ZRLE_PIXEL
-#undef ZRLE_WRITE_PIXEL
-#undef ZRLE_ENCODE
-#undef ZRLE_ENCODE_TILE
-#undef ZYWRLE_ENCODE_TILE
-#undef ZRLE_BPP_OUT
-#undef ZRLE_WRITE_SUFFIX
-#undef ZRLE_ENCODE_SUFFIX
diff --git a/qemu/ui/vnc-enc-zrle.c b/qemu/ui/vnc-enc-zrle.c
deleted file mode 100644
index 5489870e7..000000000
--- a/qemu/ui/vnc-enc-zrle.c
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * QEMU VNC display driver: Zlib Run-length Encoding (ZRLE)
- *
- * From libvncserver/libvncserver/zrle.c
- * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
- * Copyright (C) 2003 Sun Microsystems, Inc.
- *
- * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "vnc.h"
-#include "vnc-enc-zrle.h"
-
-static const int bits_per_packed_pixel[] = {
- 0, 1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
-};
-
-
-static void vnc_zrle_start(VncState *vs)
-{
- buffer_reset(&vs->zrle.zrle);
-
- /* make the output buffer be the zlib buffer, so we can compress it later */
- vs->zrle.tmp = vs->output;
- vs->output = vs->zrle.zrle;
-}
-
-static void vnc_zrle_stop(VncState *vs)
-{
- /* switch back to normal output/zlib buffers */
- vs->zrle.zrle = vs->output;
- vs->output = vs->zrle.tmp;
-}
-
-static void *zrle_convert_fb(VncState *vs, int x, int y, int w, int h,
- int bpp)
-{
- Buffer tmp;
-
- buffer_reset(&vs->zrle.fb);
- buffer_reserve(&vs->zrle.fb, w * h * bpp + bpp);
-
- tmp = vs->output;
- vs->output = vs->zrle.fb;
-
- vnc_raw_send_framebuffer_update(vs, x, y, w, h);
-
- vs->zrle.fb = vs->output;
- vs->output = tmp;
- return vs->zrle.fb.buffer;
-}
-
-static int zrle_compress_data(VncState *vs, int level)
-{
- z_streamp zstream = &vs->zrle.stream;
-
- buffer_reset(&vs->zrle.zlib);
-
- if (zstream->opaque != vs) {
- int err;
-
- zstream->zalloc = vnc_zlib_zalloc;
- zstream->zfree = vnc_zlib_zfree;
-
- err = deflateInit2(zstream, level, Z_DEFLATED, MAX_WBITS,
- MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
-
- if (err != Z_OK) {
- fprintf(stderr, "VNC: error initializing zlib\n");
- return -1;
- }
-
- zstream->opaque = vs;
- }
-
- /* reserve memory in output buffer */
- buffer_reserve(&vs->zrle.zlib, vs->zrle.zrle.offset + 64);
-
- /* set pointers */
- zstream->next_in = vs->zrle.zrle.buffer;
- zstream->avail_in = vs->zrle.zrle.offset;
- zstream->next_out = vs->zrle.zlib.buffer + vs->zrle.zlib.offset;
- zstream->avail_out = vs->zrle.zlib.capacity - vs->zrle.zlib.offset;
- zstream->data_type = Z_BINARY;
-
- /* start encoding */
- if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
- fprintf(stderr, "VNC: error during zrle compression\n");
- return -1;
- }
-
- vs->zrle.zlib.offset = vs->zrle.zlib.capacity - zstream->avail_out;
- return vs->zrle.zlib.offset;
-}
-
-/* Try to work out whether to use RLE and/or a palette. We do this by
- * estimating the number of bytes which will be generated and picking the
- * method which results in the fewest bytes. Of course this may not result
- * in the fewest bytes after compression... */
-static void zrle_choose_palette_rle(VncState *vs, int w, int h,
- VncPalette *palette, int bpp_out,
- int runs, int single_pixels,
- int zywrle_level,
- bool *use_rle, bool *use_palette)
-{
- size_t estimated_bytes;
- size_t plain_rle_bytes;
-
- *use_palette = *use_rle = false;
-
- estimated_bytes = w * h * (bpp_out / 8); /* start assuming raw */
-
- if (bpp_out != 8) {
- if (zywrle_level > 0 && !(zywrle_level & 0x80))
- estimated_bytes >>= zywrle_level;
- }
-
- plain_rle_bytes = ((bpp_out / 8) + 1) * (runs + single_pixels);
-
- if (plain_rle_bytes < estimated_bytes) {
- *use_rle = true;
- estimated_bytes = plain_rle_bytes;
- }
-
- if (palette_size(palette) < 128) {
- int palette_rle_bytes;
-
- palette_rle_bytes = (bpp_out / 8) * palette_size(palette);
- palette_rle_bytes += 2 * runs + single_pixels;
-
- if (palette_rle_bytes < estimated_bytes) {
- *use_rle = true;
- *use_palette = true;
- estimated_bytes = palette_rle_bytes;
- }
-
- if (palette_size(palette) < 17) {
- int packed_bytes;
-
- packed_bytes = (bpp_out / 8) * palette_size(palette);
- packed_bytes += w * h *
- bits_per_packed_pixel[palette_size(palette)-1] / 8;
-
- if (packed_bytes < estimated_bytes) {
- *use_rle = false;
- *use_palette = true;
- estimated_bytes = packed_bytes;
- }
- }
- }
-}
-
-static void zrle_write_u32(VncState *vs, uint32_t value)
-{
- vnc_write(vs, (uint8_t *)&value, 4);
-}
-
-static void zrle_write_u24a(VncState *vs, uint32_t value)
-{
- vnc_write(vs, (uint8_t *)&value, 3);
-}
-
-static void zrle_write_u24b(VncState *vs, uint32_t value)
-{
- vnc_write(vs, ((uint8_t *)&value) + 1, 3);
-}
-
-static void zrle_write_u16(VncState *vs, uint16_t value)
-{
- vnc_write(vs, (uint8_t *)&value, 2);
-}
-
-static void zrle_write_u8(VncState *vs, uint8_t value)
-{
- vnc_write_u8(vs, value);
-}
-
-#define ENDIAN_LITTLE 0
-#define ENDIAN_BIG 1
-#define ENDIAN_NO 2
-
-#define ZRLE_BPP 8
-#define ZYWRLE_ENDIAN ENDIAN_NO
-#include "vnc-enc-zrle-template.c"
-#undef ZRLE_BPP
-
-#define ZRLE_BPP 15
-#undef ZYWRLE_ENDIAN
-#define ZYWRLE_ENDIAN ENDIAN_LITTLE
-#include "vnc-enc-zrle-template.c"
-
-#undef ZYWRLE_ENDIAN
-#define ZYWRLE_ENDIAN ENDIAN_BIG
-#include "vnc-enc-zrle-template.c"
-
-#undef ZRLE_BPP
-#define ZRLE_BPP 16
-#undef ZYWRLE_ENDIAN
-#define ZYWRLE_ENDIAN ENDIAN_LITTLE
-#include "vnc-enc-zrle-template.c"
-
-#undef ZYWRLE_ENDIAN
-#define ZYWRLE_ENDIAN ENDIAN_BIG
-#include "vnc-enc-zrle-template.c"
-
-#undef ZRLE_BPP
-#define ZRLE_BPP 32
-#undef ZYWRLE_ENDIAN
-#define ZYWRLE_ENDIAN ENDIAN_LITTLE
-#include "vnc-enc-zrle-template.c"
-
-#undef ZYWRLE_ENDIAN
-#define ZYWRLE_ENDIAN ENDIAN_BIG
-#include "vnc-enc-zrle-template.c"
-
-#define ZRLE_COMPACT_PIXEL 24a
-#undef ZYWRLE_ENDIAN
-#define ZYWRLE_ENDIAN ENDIAN_LITTLE
-#include "vnc-enc-zrle-template.c"
-
-#undef ZYWRLE_ENDIAN
-#define ZYWRLE_ENDIAN ENDIAN_BIG
-#include "vnc-enc-zrle-template.c"
-
-#undef ZRLE_COMPACT_PIXEL
-#define ZRLE_COMPACT_PIXEL 24b
-#undef ZYWRLE_ENDIAN
-#define ZYWRLE_ENDIAN ENDIAN_LITTLE
-#include "vnc-enc-zrle-template.c"
-
-#undef ZYWRLE_ENDIAN
-#define ZYWRLE_ENDIAN ENDIAN_BIG
-#include "vnc-enc-zrle-template.c"
-#undef ZRLE_COMPACT_PIXEL
-#undef ZRLE_BPP
-
-static int zrle_send_framebuffer_update(VncState *vs, int x, int y,
- int w, int h)
-{
- bool be = vs->client_be;
- size_t bytes;
- int zywrle_level;
-
- if (vs->zrle.type == VNC_ENCODING_ZYWRLE) {
- if (!vs->vd->lossy || vs->tight.quality == (uint8_t)-1
- || vs->tight.quality == 9) {
- zywrle_level = 0;
- vs->zrle.type = VNC_ENCODING_ZRLE;
- } else if (vs->tight.quality < 3) {
- zywrle_level = 3;
- } else if (vs->tight.quality < 6) {
- zywrle_level = 2;
- } else {
- zywrle_level = 1;
- }
- } else {
- zywrle_level = 0;
- }
-
- vnc_zrle_start(vs);
-
- switch (vs->client_pf.bytes_per_pixel) {
- case 1:
- zrle_encode_8ne(vs, x, y, w, h, zywrle_level);
- break;
-
- case 2:
- if (vs->client_pf.gmax > 0x1F) {
- if (be) {
- zrle_encode_16be(vs, x, y, w, h, zywrle_level);
- } else {
- zrle_encode_16le(vs, x, y, w, h, zywrle_level);
- }
- } else {
- if (be) {
- zrle_encode_15be(vs, x, y, w, h, zywrle_level);
- } else {
- zrle_encode_15le(vs, x, y, w, h, zywrle_level);
- }
- }
- break;
-
- case 4:
- {
- bool fits_in_ls3bytes;
- bool fits_in_ms3bytes;
-
- fits_in_ls3bytes =
- ((vs->client_pf.rmax << vs->client_pf.rshift) < (1 << 24) &&
- (vs->client_pf.gmax << vs->client_pf.gshift) < (1 << 24) &&
- (vs->client_pf.bmax << vs->client_pf.bshift) < (1 << 24));
-
- fits_in_ms3bytes = (vs->client_pf.rshift > 7 &&
- vs->client_pf.gshift > 7 &&
- vs->client_pf.bshift > 7);
-
- if ((fits_in_ls3bytes && !be) || (fits_in_ms3bytes && be)) {
- if (be) {
- zrle_encode_24abe(vs, x, y, w, h, zywrle_level);
- } else {
- zrle_encode_24ale(vs, x, y, w, h, zywrle_level);
- }
- } else if ((fits_in_ls3bytes && be) || (fits_in_ms3bytes && !be)) {
- if (be) {
- zrle_encode_24bbe(vs, x, y, w, h, zywrle_level);
- } else {
- zrle_encode_24ble(vs, x, y, w, h, zywrle_level);
- }
- } else {
- if (be) {
- zrle_encode_32be(vs, x, y, w, h, zywrle_level);
- } else {
- zrle_encode_32le(vs, x, y, w, h, zywrle_level);
- }
- }
- }
- break;
- }
-
- vnc_zrle_stop(vs);
- bytes = zrle_compress_data(vs, Z_DEFAULT_COMPRESSION);
- vnc_framebuffer_update(vs, x, y, w, h, vs->zrle.type);
- vnc_write_u32(vs, bytes);
- vnc_write(vs, vs->zrle.zlib.buffer, vs->zrle.zlib.offset);
- return 1;
-}
-
-int vnc_zrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
-{
- vs->zrle.type = VNC_ENCODING_ZRLE;
- return zrle_send_framebuffer_update(vs, x, y, w, h);
-}
-
-int vnc_zywrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
-{
- vs->zrle.type = VNC_ENCODING_ZYWRLE;
- return zrle_send_framebuffer_update(vs, x, y, w, h);
-}
-
-void vnc_zrle_clear(VncState *vs)
-{
- if (vs->zrle.stream.opaque) {
- deflateEnd(&vs->zrle.stream);
- }
- buffer_free(&vs->zrle.zrle);
- buffer_free(&vs->zrle.fb);
- buffer_free(&vs->zrle.zlib);
-}
diff --git a/qemu/ui/vnc-enc-zrle.h b/qemu/ui/vnc-enc-zrle.h
deleted file mode 100644
index 6b182132a..000000000
--- a/qemu/ui/vnc-enc-zrle.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * QEMU VNC display driver: Zlib Run-length Encoding (ZRLE)
- *
- * From libvncserver/libvncserver/zrle.c
- * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved.
- * Copyright (C) 2003 Sun Microsystems, Inc.
- *
- * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef VNC_ENCODING_ZRLE_H
-#define VNC_ENCODING_ZRLE_H
-
-/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * ZRLE - encoding combining Zlib compression, tiling, palettisation and
- * run-length encoding.
- */
-
-#define VNC_ZRLE_TILE_WIDTH 64
-#define VNC_ZRLE_TILE_HEIGHT 64
-
-#endif
diff --git a/qemu/ui/vnc-enc-zywrle-template.c b/qemu/ui/vnc-enc-zywrle-template.c
deleted file mode 100644
index b446380a7..000000000
--- a/qemu/ui/vnc-enc-zywrle-template.c
+++ /dev/null
@@ -1,171 +0,0 @@
-
-/********************************************************************
- * *
- * THIS FILE IS PART OF THE 'ZYWRLE' VNC CODEC SOURCE CODE. *
- * *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
- * GOVERNED BY A FOLLOWING BSD-STYLE SOURCE LICENSE. *
- * PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
- * *
- * THE 'ZYWRLE' VNC CODEC SOURCE CODE IS (C) COPYRIGHT 2006 *
- * BY Hitachi Systems & Services, Ltd. *
- * (Noriaki Yamazaki, Research & Development Center) *
- * *
- * *
- ********************************************************************
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-- Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-
-- Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-
-- Neither the name of the Hitachi Systems & Services, Ltd. nor
-the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
-OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- ********************************************************************/
-
-/* Change Log:
- V0.02 : 2008/02/04 : Fix mis encode/decode when width != scanline
- (Thanks Johannes Schindelin, author of LibVNC
- Server/Client)
- V0.01 : 2007/02/06 : Initial release
-*/
-
-/*
-[References]
- PLHarr:
- Senecal, J. G., P. Lindstrom, M. A. Duchaineau, and K. I. Joy,
- "An Improved N-Bit to N-Bit Reversible Haar-Like Transform,"
- Pacific Graphics 2004, October 2004, pp. 371-380.
- EZW:
- Shapiro, JM: Embedded Image Coding Using Zerotrees of Wavelet Coefficients,
- IEEE Trans. Signal. Process., Vol.41, pp.3445-3462 (1993).
-*/
-
-
-/* Template Macro stuffs. */
-#undef ZYWRLE_ANALYZE
-#undef ZYWRLE_SYNTHESIZE
-
-#define ZYWRLE_SUFFIX ZRLE_CONCAT2(ZRLE_BPP,ZRLE_ENDIAN_SUFFIX)
-
-#define ZYWRLE_ANALYZE ZRLE_CONCAT2(zywrle_analyze_, ZYWRLE_SUFFIX)
-#define ZYWRLE_SYNTHESIZE ZRLE_CONCAT2(zywrle_synthesize_,ZYWRLE_SUFFIX)
-
-#define ZYWRLE_RGBYUV ZRLE_CONCAT2(zywrle_rgbyuv_, ZYWRLE_SUFFIX)
-#define ZYWRLE_YUVRGB ZRLE_CONCAT2(zywrle_yuvrgb_, ZYWRLE_SUFFIX)
-#define ZYWRLE_YMASK ZRLE_CONCAT2(ZYWRLE_YMASK, ZRLE_BPP)
-#define ZYWRLE_UVMASK ZRLE_CONCAT2(ZYWRLE_UVMASK, ZRLE_BPP)
-#define ZYWRLE_LOAD_PIXEL ZRLE_CONCAT2(ZYWRLE_LOAD_PIXEL, ZRLE_BPP)
-#define ZYWRLE_SAVE_PIXEL ZRLE_CONCAT2(ZYWRLE_SAVE_PIXEL, ZRLE_BPP)
-
-/* Packing/Unpacking pixel stuffs.
- Endian conversion stuffs. */
-#undef S_0
-#undef S_1
-#undef L_0
-#undef L_1
-#undef L_2
-
-#if ZYWRLE_ENDIAN == ENDIAN_BIG
-# define S_0 1
-# define S_1 0
-# define L_0 3
-# define L_1 2
-# define L_2 1
-#else
-# define S_0 0
-# define S_1 1
-# define L_0 0
-# define L_1 1
-# define L_2 2
-#endif
-
-#define ZYWRLE_QUANTIZE
-#include "qemu/osdep.h"
-#include "vnc-enc-zywrle.h"
-
-#ifndef ZRLE_COMPACT_PIXEL
-static inline void ZYWRLE_RGBYUV(int *buf, ZRLE_PIXEL *data,
- int width, int height, int scanline)
-{
- int r, g, b;
- int y, u, v;
- int *line;
- int *end;
-
- end = buf + height * width;
- while (buf < end) {
- line = buf + width;
- while (buf < line) {
- ZYWRLE_LOAD_PIXEL(data, r, g, b);
- ZYWRLE_RGBYUV_(r, g, b, y, u, v, ZYWRLE_YMASK, ZYWRLE_UVMASK);
- ZYWRLE_SAVE_COEFF(buf, v, y, u);
- buf++;
- data++;
- }
- data += scanline - width;
- }
-}
-
-static ZRLE_PIXEL *ZYWRLE_ANALYZE(ZRLE_PIXEL *dst, ZRLE_PIXEL *src,
- int w, int h, int scanline, int level,
- int *buf) {
- int l;
- int uw = w;
- int uh = h;
- int *top;
- int *end;
- int *line;
- ZRLE_PIXEL *p;
- int r, g, b;
- int s;
- int *ph;
-
- zywrle_calc_size(&w, &h, level);
-
- if (w == 0 || h == 0) {
- return NULL;
- }
- uw -= w;
- uh -= h;
-
- p = dst;
- ZYWRLE_LOAD_UNALIGN(src,*(ZRLE_PIXEL*)top = *p;);
- ZYWRLE_RGBYUV(buf, src, w, h, scanline);
- wavelet(buf, w, h, level);
- for (l = 0; l < level; l++) {
- ZYWRLE_PACK_COEFF(buf, dst, 3, w, h, scanline, l);
- ZYWRLE_PACK_COEFF(buf, dst, 2, w, h, scanline, l);
- ZYWRLE_PACK_COEFF(buf, dst, 1, w, h, scanline, l);
- if (l == level - 1) {
- ZYWRLE_PACK_COEFF(buf, dst, 0, w, h, scanline, l);
- }
- }
- ZYWRLE_SAVE_UNALIGN(dst,*dst = *(ZRLE_PIXEL*)top;);
- return dst;
-}
-#endif /* ZRLE_COMPACT_PIXEL */
-
-#undef ZYWRLE_RGBYUV
-#undef ZYWRLE_YUVRGB
-#undef ZYWRLE_LOAD_PIXEL
-#undef ZYWRLE_SAVE_PIXEL
diff --git a/qemu/ui/vnc-enc-zywrle.h b/qemu/ui/vnc-enc-zywrle.h
deleted file mode 100644
index d436d588f..000000000
--- a/qemu/ui/vnc-enc-zywrle.h
+++ /dev/null
@@ -1,659 +0,0 @@
-/********************************************************************
- * *
- * THIS FILE IS PART OF THE 'ZYWRLE' VNC CODEC SOURCE CODE. *
- * *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
- * GOVERNED BY A FOLLOWING BSD-STYLE SOURCE LICENSE. *
- * PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
- * *
- * THE 'ZYWRLE' VNC CODEC SOURCE CODE IS (C) COPYRIGHT 2006 *
- * BY Hitachi Systems & Services, Ltd. *
- * (Noriaki Yamazaki, Research & Development Center) *
- * *
- * *
- ********************************************************************
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-- Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-
-- Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-
-- Neither the name of the Hitachi Systems & Services, Ltd. nor
-the names of its contributors may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
-OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- ********************************************************************/
-
-#ifndef VNC_ENCODING_ZYWRLE_H
-#define VNC_ENCODING_ZYWRLE_H
-
-/* Tables for Coefficients filtering. */
-#ifndef ZYWRLE_QUANTIZE
-/* Type A:lower bit omitting of EZW style. */
-static const unsigned int zywrle_param[3][3]={
- {0x0000F000, 0x00000000, 0x00000000},
- {0x0000C000, 0x00F0F0F0, 0x00000000},
- {0x0000C000, 0x00C0C0C0, 0x00F0F0F0},
-/* {0x0000FF00, 0x00000000, 0x00000000},
- {0x0000FF00, 0x00FFFFFF, 0x00000000},
- {0x0000FF00, 0x00FFFFFF, 0x00FFFFFF}, */
-};
-#else
-/* Type B:Non liner quantization filter. */
-static const int8_t zywrle_conv[4][256]={
-{ /* bi=5, bo=5 r=0.0:PSNR=24.849 */
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
-},
-{ /* bi=5, bo=5 r=2.0:PSNR=74.031 */
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,
- 32, 32, 32, 32, 32, 32, 32, 32,
- 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 64, 64, 64, 64,
- 64, 64, 64, 64, 72, 72, 72, 72,
- 72, 72, 72, 72, 80, 80, 80, 80,
- 80, 80, 88, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 88, 96, 96,
- 96, 96, 96, 104, 104, 104, 104, 104,
- 104, 104, 104, 104, 104, 112, 112, 112,
- 112, 112, 112, 112, 112, 112, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120,
- 0, -120, -120, -120, -120, -120, -120, -120,
- -120, -120, -120, -112, -112, -112, -112, -112,
- -112, -112, -112, -112, -104, -104, -104, -104,
- -104, -104, -104, -104, -104, -104, -96, -96,
- -96, -96, -96, -88, -88, -88, -88, -88,
- -88, -88, -88, -88, -88, -88, -88, -80,
- -80, -80, -80, -80, -80, -72, -72, -72,
- -72, -72, -72, -72, -72, -64, -64, -64,
- -64, -64, -64, -64, -64, -56, -56, -56,
- -56, -56, -56, -56, -56, -56, -48, -48,
- -48, -48, -48, -48, -48, -48, -48, -48,
- -48, -32, -32, -32, -32, -32, -32, -32,
- -32, -32, -32, -32, -32, -32, -32, -32,
- -32, -32, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
-},
-{ /* bi=5, bo=4 r=2.0:PSNR=64.441 */
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 48, 48,
- 48, 48, 48, 48, 48, 48, 48, 48,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64,
- 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 88, 88, 88,
- 88, 88, 88, 88, 88, 88, 88, 88,
- 104, 104, 104, 104, 104, 104, 104, 104,
- 104, 104, 104, 112, 112, 112, 112, 112,
- 112, 112, 112, 112, 120, 120, 120, 120,
- 120, 120, 120, 120, 120, 120, 120, 120,
- 0, -120, -120, -120, -120, -120, -120, -120,
- -120, -120, -120, -120, -120, -112, -112, -112,
- -112, -112, -112, -112, -112, -112, -104, -104,
- -104, -104, -104, -104, -104, -104, -104, -104,
- -104, -88, -88, -88, -88, -88, -88, -88,
- -88, -88, -88, -88, -80, -80, -80, -80,
- -80, -80, -80, -80, -80, -80, -80, -80,
- -80, -64, -64, -64, -64, -64, -64, -64,
- -64, -64, -64, -64, -64, -64, -64, -64,
- -64, -48, -48, -48, -48, -48, -48, -48,
- -48, -48, -48, -48, -48, -48, -48, -48,
- -48, -48, -48, -48, -48, -48, -48, -48,
- -48, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
-},
-{ /* bi=5, bo=2 r=2.0:PSNR=43.175 */
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 88, 88, 88, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 88, 88, 88,
- 0, -88, -88, -88, -88, -88, -88, -88,
- -88, -88, -88, -88, -88, -88, -88, -88,
- -88, -88, -88, -88, -88, -88, -88, -88,
- -88, -88, -88, -88, -88, -88, -88, -88,
- -88, -88, -88, -88, -88, -88, -88, -88,
- -88, -88, -88, -88, -88, -88, -88, -88,
- -88, -88, -88, -88, -88, -88, -88, -88,
- -88, -88, -88, -88, -88, -88, -88, -88,
- -88, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
-}
-};
-
-static const int8_t *zywrle_param[3][3][3]={
- {{zywrle_conv[0], zywrle_conv[2], zywrle_conv[0]},
- {zywrle_conv[0], zywrle_conv[0], zywrle_conv[0]},
- {zywrle_conv[0], zywrle_conv[0], zywrle_conv[0]}},
- {{zywrle_conv[0], zywrle_conv[3], zywrle_conv[0]},
- {zywrle_conv[1], zywrle_conv[1], zywrle_conv[1]},
- {zywrle_conv[0], zywrle_conv[0], zywrle_conv[0]}},
- {{zywrle_conv[0], zywrle_conv[3], zywrle_conv[0]},
- {zywrle_conv[2], zywrle_conv[2], zywrle_conv[2]},
- {zywrle_conv[1], zywrle_conv[1], zywrle_conv[1]}},
-};
-#endif
-
-/* Load/Save pixel stuffs. */
-#define ZYWRLE_YMASK15 0xFFFFFFF8
-#define ZYWRLE_UVMASK15 0xFFFFFFF8
-#define ZYWRLE_LOAD_PIXEL15(src, r, g, b) \
- do { \
- r = (((uint8_t*)src)[S_1]<< 1)& 0xF8; \
- g = (((uint8_t*)src)[S_1]<< 6) | (((uint8_t*)src)[S_0]>> 2); \
- g &= 0xF8; \
- b = (((uint8_t*)src)[S_0]<< 3)& 0xF8; \
- } while (0)
-
-#define ZYWRLE_SAVE_PIXEL15(dst, r, g, b) \
- do { \
- r &= 0xF8; \
- g &= 0xF8; \
- b &= 0xF8; \
- ((uint8_t*)dst)[S_1] = (uint8_t)((r >> 1)|(g >> 6)); \
- ((uint8_t*)dst)[S_0] = (uint8_t)(((b >> 3)|(g << 2))& 0xFF); \
- } while (0)
-
-#define ZYWRLE_YMASK16 0xFFFFFFFC
-#define ZYWRLE_UVMASK16 0xFFFFFFF8
-#define ZYWRLE_LOAD_PIXEL16(src, r, g, b) \
- do { \
- r = ((uint8_t*)src)[S_1] & 0xF8; \
- g = (((uint8_t*)src)[S_1]<< 5) | (((uint8_t*)src)[S_0] >> 3); \
- g &= 0xFC; \
- b = (((uint8_t*)src)[S_0]<< 3) & 0xF8; \
- } while (0)
-
-#define ZYWRLE_SAVE_PIXEL16(dst, r, g,b) \
- do { \
- r &= 0xF8; \
- g &= 0xFC; \
- b &= 0xF8; \
- ((uint8_t*)dst)[S_1] = (uint8_t)(r | (g >> 5)); \
- ((uint8_t*)dst)[S_0] = (uint8_t)(((b >> 3)|(g << 3)) & 0xFF); \
- } while (0)
-
-#define ZYWRLE_YMASK32 0xFFFFFFFF
-#define ZYWRLE_UVMASK32 0xFFFFFFFF
-#define ZYWRLE_LOAD_PIXEL32(src, r, g, b) \
- do { \
- r = ((uint8_t*)src)[L_2]; \
- g = ((uint8_t*)src)[L_1]; \
- b = ((uint8_t*)src)[L_0]; \
- } while (0)
-#define ZYWRLE_SAVE_PIXEL32(dst, r, g, b) \
- do { \
- ((uint8_t*)dst)[L_2] = (uint8_t)r; \
- ((uint8_t*)dst)[L_1] = (uint8_t)g; \
- ((uint8_t*)dst)[L_0] = (uint8_t)b; \
- } while (0)
-
-static inline void harr(int8_t *px0, int8_t *px1)
-{
- /* Piecewise-Linear Harr(PLHarr) */
- int x0 = (int)*px0, x1 = (int)*px1;
- int orgx0 = x0, orgx1 = x1;
-
- if ((x0 ^ x1) & 0x80) {
- /* differ sign */
- x1 += x0;
- if (((x1 ^ orgx1) & 0x80) == 0) {
- /* |x1| > |x0| */
- x0 -= x1; /* H = -B */
- }
- } else {
- /* same sign */
- x0 -= x1;
- if (((x0 ^ orgx0) & 0x80) == 0) {
- /* |x0| > |x1| */
- x1 += x0; /* L = A */
- }
- }
- *px0 = (int8_t)x1;
- *px1 = (int8_t)x0;
-}
-
-/*
- 1D-Wavelet transform.
-
- In coefficients array, the famous 'pyramid' decomposition is well used.
-
- 1D Model:
- |L0L0L0L0|L0L0L0L0|H0H0H0H0|H0H0H0H0| : level 0
- |L1L1L1L1|H1H1H1H1|H0H0H0H0|H0H0H0H0| : level 1
-
- But this method needs line buffer because H/L is different position from X0/X1.
- So, I used 'interleave' decomposition instead of it.
-
- 1D Model:
- |L0H0L0H0|L0H0L0H0|L0H0L0H0|L0H0L0H0| : level 0
- |L1H0H1H0|L1H0H1H0|L1H0H1H0|L1H0H1H0| : level 1
-
- In this method, H/L and X0/X1 is always same position.
- This leads us to more speed and less memory.
- Of cause, the result of both method is quite same
- because it's only difference that coefficient position.
-*/
-static inline void wavelet_level(int *data, int size, int l, int skip_pixel)
-{
- int s, ofs;
- int8_t *px0;
- int8_t *end;
-
- px0 = (int8_t*)data;
- s = (8 << l) * skip_pixel;
- end = px0 + (size >> (l + 1)) * s;
- s -= 2;
- ofs = (4 << l) * skip_pixel;
-
- while (px0 < end) {
- harr(px0, px0 + ofs);
- px0++;
- harr(px0, px0 + ofs);
- px0++;
- harr(px0, px0 + ofs);
- px0 += s;
- }
-}
-
-#ifndef ZYWRLE_QUANTIZE
-/* Type A:lower bit omitting of EZW style. */
-static inline void filter_wavelet_square(int *buf, int width, int height,
- int level, int l)
-{
- int r, s;
- int x, y;
- int *h;
- const unsigned int *m;
-
- m = &(zywrle_param[level - 1][l]);
- s = 2 << l;
-
- for (r = 1; r < 4; r++) {
- h = buf;
- if (r & 0x01) {
- h += s >> 1;
- }
- if (r & 0x02) {
- h += (s >> 1) * width;
- }
- for (y = 0; y < height / s; y++) {
- for (x = 0; x < width / s; x++) {
- /*
- these are same following code.
- h[x] = h[x] / (~m[x]+1) * (~m[x]+1);
- ( round h[x] with m[x] bit )
- '&' operator isn't 'round' but is 'floor'.
- So, we must offset when h[x] is negative.
- */
- if (((int8_t*)h)[0] & 0x80) {
- ((int8_t*)h)[0] += ~((int8_t*)m)[0];
- }
- if (((int8_t*)h)[1] & 0x80) {
- ((int8_t*)h)[1] += ~((int8_t*)m)[1];
- }
- if (((int8_t*)h)[2] & 0x80) {
- ((int8_t*)h)[2] += ~((int8_t*)m)[2];
- }
- *h &= *m;
- h += s;
- }
- h += (s-1)*width;
- }
- }
-}
-#else
-/*
- Type B:Non liner quantization filter.
-
- Coefficients have Gaussian curve and smaller value which is
- large part of coefficients isn't more important than larger value.
- So, I use filter of Non liner quantize/dequantize table.
- In general, Non liner quantize formula is explained as following.
-
- y=f(x) = sign(x)*round( ((abs(x)/(2^7))^ r )* 2^(bo-1) )*2^(8-bo)
- x=f-1(y) = sign(y)*round( ((abs(y)/(2^7))^(1/r))* 2^(bi-1) )*2^(8-bi)
- ( r:power coefficient bi:effective MSB in input bo:effective MSB in output )
-
- r < 1.0 : Smaller value is more important than larger value.
- r > 1.0 : Larger value is more important than smaller value.
- r = 1.0 : Liner quantization which is same with EZW style.
-
- r = 0.75 is famous non liner quantization used in MP3 audio codec.
- In contrast to audio data, larger value is important in wavelet coefficients.
- So, I select r = 2.0 table( quantize is x^2, dequantize sqrt(x) ).
-
- As compared with EZW style liner quantization, this filter tended to be
- more sharp edge and be more compression rate but be more blocking noise and be
- less quality. Especially, the surface of graphic objects has distinguishable
- noise in middle quality mode.
-
- We need only quantized-dequantized(filtered) value rather than quantized value
- itself because all values are packed or palette-lized in later ZRLE section.
- This lead us not to need to modify client decoder when we change
- the filtering procedure in future.
- Client only decodes coefficients given by encoder.
-*/
-static inline void filter_wavelet_square(int *buf, int width, int height,
- int level, int l)
-{
- int r, s;
- int x, y;
- int *h;
- const int8_t **m;
-
- m = zywrle_param[level - 1][l];
- s = 2 << l;
-
- for (r = 1; r < 4; r++) {
- h = buf;
- if (r & 0x01) {
- h += s >> 1;
- }
- if (r & 0x02) {
- h += (s >> 1) * width;
- }
- for (y = 0; y < height / s; y++) {
- for (x = 0; x < width / s; x++) {
- ((int8_t*)h)[0] = m[0][((uint8_t*)h)[0]];
- ((int8_t*)h)[1] = m[1][((uint8_t*)h)[1]];
- ((int8_t*)h)[2] = m[2][((uint8_t*)h)[2]];
- h += s;
- }
- h += (s - 1) * width;
- }
- }
-}
-#endif
-
-static inline void wavelet(int *buf, int width, int height, int level)
-{
- int l, s;
- int *top;
- int *end;
-
- for (l = 0; l < level; l++) {
- top = buf;
- end = buf + height * width;
- s = width << l;
- while (top < end) {
- wavelet_level(top, width, l, 1);
- top += s;
- }
- top = buf;
- end = buf + width;
- s = 1<<l;
- while (top < end) {
- wavelet_level(top, height, l, width);
- top += s;
- }
- filter_wavelet_square(buf, width, height, level, l);
- }
-}
-
-
-/* Load/Save coefficients stuffs.
- Coefficients manages as 24 bits little-endian pixel. */
-#define ZYWRLE_LOAD_COEFF(src, r, g, b) \
- do { \
- r = ((int8_t*)src)[2]; \
- g = ((int8_t*)src)[1]; \
- b = ((int8_t*)src)[0]; \
- } while (0)
-
-#define ZYWRLE_SAVE_COEFF(dst, r, g, b) \
- do { \
- ((int8_t*)dst)[2] = (int8_t)r; \
- ((int8_t*)dst)[1] = (int8_t)g; \
- ((int8_t*)dst)[0] = (int8_t)b; \
- } while (0)
-
-/*
- RGB <=> YUV conversion stuffs.
- YUV coversion is explained as following formula in strict meaning:
- Y = 0.299R + 0.587G + 0.114B ( 0<=Y<=255)
- U = -0.169R - 0.331G + 0.500B (-128<=U<=127)
- V = 0.500R - 0.419G - 0.081B (-128<=V<=127)
-
- I use simple conversion RCT(reversible color transform) which is described
- in JPEG-2000 specification.
- Y = (R + 2G + B)/4 ( 0<=Y<=255)
- U = B-G (-256<=U<=255)
- V = R-G (-256<=V<=255)
-*/
-
-/* RCT is N-bit RGB to N-bit Y and N+1-bit UV.
- For make Same N-bit, UV is lossy.
- More exact PLHarr, we reduce to odd range(-127<=x<=127). */
-#define ZYWRLE_RGBYUV_(r, g, b, y, u, v, ymask, uvmask) \
- do { \
- y = (r + (g << 1) + b) >> 2; \
- u = b - g; \
- v = r - g; \
- y -= 128; \
- u >>= 1; \
- v >>= 1; \
- y &= ymask; \
- u &= uvmask; \
- v &= uvmask; \
- if (y == -128) { \
- y += (0xFFFFFFFF - ymask + 1); \
- } \
- if (u == -128) { \
- u += (0xFFFFFFFF - uvmask + 1); \
- } \
- if (v == -128) { \
- v += (0xFFFFFFFF - uvmask + 1); \
- } \
- } while (0)
-
-
-/*
- coefficient packing/unpacking stuffs.
- Wavelet transform makes 4 sub coefficient image from 1 original image.
-
- model with pyramid decomposition:
- +------+------+
- | | |
- | L | Hx |
- | | |
- +------+------+
- | | |
- | H | Hxy |
- | | |
- +------+------+
-
- So, we must transfer each sub images individually in strict meaning.
- But at least ZRLE meaning, following one decompositon image is same as
- avobe individual sub image. I use this format.
- (Strictly saying, transfer order is reverse(Hxy->Hy->Hx->L)
- for simplified procedure for any wavelet level.)
-
- +------+------+
- | L |
- +------+------+
- | Hx |
- +------+------+
- | Hy |
- +------+------+
- | Hxy |
- +------+------+
-*/
-#define ZYWRLE_INC_PTR(data) \
- do { \
- data++; \
- if( data - p >= (w + uw) ) { \
- data += scanline-(w + uw); \
- p = data; \
- } \
- } while (0)
-
-#define ZYWRLE_TRANSFER_COEFF(buf, data, t, w, h, scanline, level, TRANS) \
- do { \
- ph = buf; \
- s = 2 << level; \
- if (t & 0x01) { \
- ph += s >> 1; \
- } \
- if (t & 0x02) { \
- ph += (s >> 1) * w; \
- } \
- end = ph + h * w; \
- while (ph < end) { \
- line = ph + w; \
- while (ph < line) { \
- TRANS \
- ZYWRLE_INC_PTR(data); \
- ph += s; \
- } \
- ph += (s - 1) * w; \
- } \
- } while (0)
-
-#define ZYWRLE_PACK_COEFF(buf, data, t, width, height, scanline, level) \
- ZYWRLE_TRANSFER_COEFF(buf, data, t, width, height, scanline, level, \
- ZYWRLE_LOAD_COEFF(ph, r, g, b); \
- ZYWRLE_SAVE_PIXEL(data, r, g, b);)
-
-#define ZYWRLE_UNPACK_COEFF(buf, data, t, width, height, scanline, level) \
- ZYWRLE_TRANSFER_COEFF(buf, data, t, width, height, scanline, level, \
- ZYWRLE_LOAD_PIXEL(data, r, g, b); \
- ZYWRLE_SAVE_COEFF(ph, r, g, b);)
-
-#define ZYWRLE_SAVE_UNALIGN(data, TRANS) \
- do { \
- top = buf + w * h; \
- end = buf + (w + uw) * (h + uh); \
- while (top < end) { \
- TRANS \
- ZYWRLE_INC_PTR(data); \
- top++; \
- } \
- } while (0)
-
-#define ZYWRLE_LOAD_UNALIGN(data,TRANS) \
- do { \
- top = buf + w * h; \
- if (uw) { \
- p = data + w; \
- end = (int*)(p + h * scanline); \
- while (p < (ZRLE_PIXEL*)end) { \
- line = (int*)(p + uw); \
- while (p < (ZRLE_PIXEL*)line) { \
- TRANS \
- p++; \
- top++; \
- } \
- p += scanline - uw; \
- } \
- } \
- if (uh) { \
- p = data + h * scanline; \
- end = (int*)(p + uh * scanline); \
- while (p < (ZRLE_PIXEL*)end) { \
- line = (int*)(p + w); \
- while (p < (ZRLE_PIXEL*)line) { \
- TRANS \
- p++; \
- top++; \
- } \
- p += scanline - w; \
- } \
- } \
- if (uw && uh) { \
- p= data + w + h * scanline; \
- end = (int*)(p + uh * scanline); \
- while (p < (ZRLE_PIXEL*)end) { \
- line = (int*)(p + uw); \
- while (p < (ZRLE_PIXEL*)line) { \
- TRANS \
- p++; \
- top++; \
- } \
- p += scanline-uw; \
- } \
- } \
- } while (0)
-
-static inline void zywrle_calc_size(int *w, int *h, int level)
-{
- *w &= ~((1 << level) - 1);
- *h &= ~((1 << level) - 1);
-}
-
-#endif
diff --git a/qemu/ui/vnc-jobs.c b/qemu/ui/vnc-jobs.c
deleted file mode 100644
index 98ca978b0..000000000
--- a/qemu/ui/vnc-jobs.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * QEMU VNC display driver
- *
- * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
- * Copyright (C) 2006 Fabrice Bellard
- * Copyright (C) 2009 Red Hat, Inc
- * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-
-#include "qemu/osdep.h"
-#include "vnc.h"
-#include "vnc-jobs.h"
-#include "qemu/sockets.h"
-#include "qemu/main-loop.h"
-#include "block/aio.h"
-
-/*
- * Locking:
- *
- * There are three levels of locking:
- * - jobs queue lock: for each operation on the queue (push, pop, isEmpty?)
- * - VncDisplay global lock: mainly used for framebuffer updates to avoid
- * screen corruption if the framebuffer is updated
- * while the worker is doing something.
- * - VncState::output lock: used to make sure the output buffer is not corrupted
- * if two threads try to write on it at the same time
- *
- * While the VNC worker thread is working, the VncDisplay global lock is held
- * to avoid screen corruption (this does not block vnc_refresh() because it
- * uses trylock()) but the output lock is not held because the thread works on
- * its own output buffer.
- * When the encoding job is done, the worker thread will hold the output lock
- * and copy its output buffer in vs->output.
- */
-
-struct VncJobQueue {
- QemuCond cond;
- QemuMutex mutex;
- QemuThread thread;
- bool exit;
- QTAILQ_HEAD(, VncJob) jobs;
-};
-
-typedef struct VncJobQueue VncJobQueue;
-
-/*
- * We use a single global queue, but most of the functions are
- * already reentrant, so we can easily add more than one encoding thread
- */
-static VncJobQueue *queue;
-
-static void vnc_lock_queue(VncJobQueue *queue)
-{
- qemu_mutex_lock(&queue->mutex);
-}
-
-static void vnc_unlock_queue(VncJobQueue *queue)
-{
- qemu_mutex_unlock(&queue->mutex);
-}
-
-VncJob *vnc_job_new(VncState *vs)
-{
- VncJob *job = g_new0(VncJob, 1);
-
- job->vs = vs;
- vnc_lock_queue(queue);
- QLIST_INIT(&job->rectangles);
- vnc_unlock_queue(queue);
- return job;
-}
-
-int vnc_job_add_rect(VncJob *job, int x, int y, int w, int h)
-{
- VncRectEntry *entry = g_new0(VncRectEntry, 1);
-
- entry->rect.x = x;
- entry->rect.y = y;
- entry->rect.w = w;
- entry->rect.h = h;
-
- vnc_lock_queue(queue);
- QLIST_INSERT_HEAD(&job->rectangles, entry, next);
- vnc_unlock_queue(queue);
- return 1;
-}
-
-void vnc_job_push(VncJob *job)
-{
- vnc_lock_queue(queue);
- if (queue->exit || QLIST_EMPTY(&job->rectangles)) {
- g_free(job);
- } else {
- QTAILQ_INSERT_TAIL(&queue->jobs, job, next);
- qemu_cond_broadcast(&queue->cond);
- }
- vnc_unlock_queue(queue);
-}
-
-static bool vnc_has_job_locked(VncState *vs)
-{
- VncJob *job;
-
- QTAILQ_FOREACH(job, &queue->jobs, next) {
- if (job->vs == vs || !vs) {
- return true;
- }
- }
- return false;
-}
-
-bool vnc_has_job(VncState *vs)
-{
- bool ret;
-
- vnc_lock_queue(queue);
- ret = vnc_has_job_locked(vs);
- vnc_unlock_queue(queue);
- return ret;
-}
-
-void vnc_jobs_clear(VncState *vs)
-{
- VncJob *job, *tmp;
-
- vnc_lock_queue(queue);
- QTAILQ_FOREACH_SAFE(job, &queue->jobs, next, tmp) {
- if (job->vs == vs || !vs) {
- QTAILQ_REMOVE(&queue->jobs, job, next);
- }
- }
- vnc_unlock_queue(queue);
-}
-
-void vnc_jobs_join(VncState *vs)
-{
- vnc_lock_queue(queue);
- while (vnc_has_job_locked(vs)) {
- qemu_cond_wait(&queue->cond, &queue->mutex);
- }
- vnc_unlock_queue(queue);
- vnc_jobs_consume_buffer(vs);
-}
-
-void vnc_jobs_consume_buffer(VncState *vs)
-{
- bool flush;
-
- vnc_lock_output(vs);
- if (vs->jobs_buffer.offset) {
- if (vs->ioc != NULL && buffer_empty(&vs->output)) {
- if (vs->ioc_tag) {
- g_source_remove(vs->ioc_tag);
- }
- vs->ioc_tag = qio_channel_add_watch(
- vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
- }
- buffer_move(&vs->output, &vs->jobs_buffer);
- }
- flush = vs->ioc != NULL && vs->abort != true;
- vnc_unlock_output(vs);
-
- if (flush) {
- vnc_flush(vs);
- }
-}
-
-/*
- * Copy data for local use
- */
-static void vnc_async_encoding_start(VncState *orig, VncState *local)
-{
- buffer_init(&local->output, "vnc-worker-output");
- local->sioc = NULL; /* Don't do any network work on this thread */
- local->ioc = NULL; /* Don't do any network work on this thread */
-
- local->vnc_encoding = orig->vnc_encoding;
- local->features = orig->features;
- local->vd = orig->vd;
- local->lossy_rect = orig->lossy_rect;
- local->write_pixels = orig->write_pixels;
- local->client_pf = orig->client_pf;
- local->client_be = orig->client_be;
- local->tight = orig->tight;
- local->zlib = orig->zlib;
- local->hextile = orig->hextile;
- local->zrle = orig->zrle;
-}
-
-static void vnc_async_encoding_end(VncState *orig, VncState *local)
-{
- orig->tight = local->tight;
- orig->zlib = local->zlib;
- orig->hextile = local->hextile;
- orig->zrle = local->zrle;
- orig->lossy_rect = local->lossy_rect;
-}
-
-static int vnc_worker_thread_loop(VncJobQueue *queue)
-{
- VncJob *job;
- VncRectEntry *entry, *tmp;
- VncState vs = {};
- int n_rectangles;
- int saved_offset;
-
- vnc_lock_queue(queue);
- while (QTAILQ_EMPTY(&queue->jobs) && !queue->exit) {
- qemu_cond_wait(&queue->cond, &queue->mutex);
- }
- /* Here job can only be NULL if queue->exit is true */
- job = QTAILQ_FIRST(&queue->jobs);
- vnc_unlock_queue(queue);
-
- if (queue->exit) {
- return -1;
- }
-
- vnc_lock_output(job->vs);
- if (job->vs->ioc == NULL || job->vs->abort == true) {
- vnc_unlock_output(job->vs);
- goto disconnected;
- }
- if (buffer_empty(&job->vs->output)) {
- /*
- * Looks like a NOP as it obviously moves no data. But it
- * moves the empty buffer, so we don't have to malloc a new
- * one for vs.output
- */
- buffer_move_empty(&vs.output, &job->vs->output);
- }
- vnc_unlock_output(job->vs);
-
- /* Make a local copy of vs and switch output buffers */
- vnc_async_encoding_start(job->vs, &vs);
-
- /* Start sending rectangles */
- n_rectangles = 0;
- vnc_write_u8(&vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
- vnc_write_u8(&vs, 0);
- saved_offset = vs.output.offset;
- vnc_write_u16(&vs, 0);
-
- vnc_lock_display(job->vs->vd);
- QLIST_FOREACH_SAFE(entry, &job->rectangles, next, tmp) {
- int n;
-
- if (job->vs->ioc == NULL) {
- vnc_unlock_display(job->vs->vd);
- /* Copy persistent encoding data */
- vnc_async_encoding_end(job->vs, &vs);
- goto disconnected;
- }
-
- n = vnc_send_framebuffer_update(&vs, entry->rect.x, entry->rect.y,
- entry->rect.w, entry->rect.h);
-
- if (n >= 0) {
- n_rectangles += n;
- }
- g_free(entry);
- }
- vnc_unlock_display(job->vs->vd);
-
- /* Put n_rectangles at the beginning of the message */
- vs.output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
- vs.output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
-
- vnc_lock_output(job->vs);
- if (job->vs->ioc != NULL) {
- buffer_move(&job->vs->jobs_buffer, &vs.output);
- /* Copy persistent encoding data */
- vnc_async_encoding_end(job->vs, &vs);
-
- qemu_bh_schedule(job->vs->bh);
- } else {
- buffer_reset(&vs.output);
- /* Copy persistent encoding data */
- vnc_async_encoding_end(job->vs, &vs);
- }
- vnc_unlock_output(job->vs);
-
-disconnected:
- vnc_lock_queue(queue);
- QTAILQ_REMOVE(&queue->jobs, job, next);
- vnc_unlock_queue(queue);
- qemu_cond_broadcast(&queue->cond);
- g_free(job);
- return 0;
-}
-
-static VncJobQueue *vnc_queue_init(void)
-{
- VncJobQueue *queue = g_new0(VncJobQueue, 1);
-
- qemu_cond_init(&queue->cond);
- qemu_mutex_init(&queue->mutex);
- QTAILQ_INIT(&queue->jobs);
- return queue;
-}
-
-static void vnc_queue_clear(VncJobQueue *q)
-{
- qemu_cond_destroy(&queue->cond);
- qemu_mutex_destroy(&queue->mutex);
- g_free(q);
- queue = NULL; /* Unset global queue */
-}
-
-static void *vnc_worker_thread(void *arg)
-{
- VncJobQueue *queue = arg;
-
- qemu_thread_get_self(&queue->thread);
-
- while (!vnc_worker_thread_loop(queue)) ;
- vnc_queue_clear(queue);
- return NULL;
-}
-
-static bool vnc_worker_thread_running(void)
-{
- return queue; /* Check global queue */
-}
-
-void vnc_start_worker_thread(void)
-{
- VncJobQueue *q;
-
- if (vnc_worker_thread_running())
- return ;
-
- q = vnc_queue_init();
- qemu_thread_create(&q->thread, "vnc_worker", vnc_worker_thread, q,
- QEMU_THREAD_DETACHED);
- queue = q; /* Set global queue */
-}
diff --git a/qemu/ui/vnc-jobs.h b/qemu/ui/vnc-jobs.h
deleted file mode 100644
index 044bf9fbf..000000000
--- a/qemu/ui/vnc-jobs.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * QEMU VNC display driver
- *
- * From libvncserver/rfb/rfbproto.h
- * Copyright (C) 2005 Rohit Kumar, Johannes E. Schindelin
- * Copyright (C) 2000-2002 Constantin Kaplinsky. All Rights Reserved.
- * Copyright (C) 2000 Tridia Corporation. All Rights Reserved.
- * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
- *
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef VNC_JOBS_H
-#define VNC_JOBS_H
-
-/* Jobs */
-VncJob *vnc_job_new(VncState *vs);
-int vnc_job_add_rect(VncJob *job, int x, int y, int w, int h);
-void vnc_job_push(VncJob *job);
-bool vnc_has_job(VncState *vs);
-void vnc_jobs_clear(VncState *vs);
-void vnc_jobs_join(VncState *vs);
-
-void vnc_jobs_consume_buffer(VncState *vs);
-void vnc_start_worker_thread(void);
-
-/* Locks */
-static inline int vnc_trylock_display(VncDisplay *vd)
-{
- return qemu_mutex_trylock(&vd->mutex);
-}
-
-static inline void vnc_lock_display(VncDisplay *vd)
-{
- qemu_mutex_lock(&vd->mutex);
-}
-
-static inline void vnc_unlock_display(VncDisplay *vd)
-{
- qemu_mutex_unlock(&vd->mutex);
-}
-
-static inline void vnc_lock_output(VncState *vs)
-{
- qemu_mutex_lock(&vs->output_mutex);
-}
-
-static inline void vnc_unlock_output(VncState *vs)
-{
- qemu_mutex_unlock(&vs->output_mutex);
-}
-
-#endif /* VNC_JOBS_H */
diff --git a/qemu/ui/vnc-palette.c b/qemu/ui/vnc-palette.c
deleted file mode 100644
index 3b89d1af2..000000000
--- a/qemu/ui/vnc-palette.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * QEMU VNC display driver: palette hash table
- *
- * From libvncserver/libvncserver/tight.c
- * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved.
- * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
- *
- * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "vnc-palette.h"
-#include <glib.h>
-
-static VncPaletteEntry *palette_find(const VncPalette *palette,
- uint32_t color, unsigned int hash)
-{
- VncPaletteEntry *entry;
-
- QLIST_FOREACH(entry, &palette->table[hash], next) {
- if (entry->color == color) {
- return entry;
- }
- }
-
- return NULL;
-}
-
-static unsigned int palette_hash(uint32_t rgb, int bpp)
-{
- if (bpp == 16) {
- return ((unsigned int)(((rgb >> 8) + rgb) & 0xFF));
- } else {
- return ((unsigned int)(((rgb >> 16) + (rgb >> 8)) & 0xFF));
- }
-}
-
-VncPalette *palette_new(size_t max, int bpp)
-{
- VncPalette *palette;
-
- palette = g_malloc0(sizeof(*palette));
- palette_init(palette, max, bpp);
- return palette;
-}
-
-void palette_init(VncPalette *palette, size_t max, int bpp)
-{
- memset(palette, 0, sizeof (*palette));
- palette->max = max;
- palette->bpp = bpp;
-}
-
-void palette_destroy(VncPalette *palette)
-{
- g_free(palette);
-}
-
-int palette_put(VncPalette *palette, uint32_t color)
-{
- unsigned int hash;
- unsigned int idx = palette->size;
- VncPaletteEntry *entry;
-
- hash = palette_hash(color, palette->bpp) % VNC_PALETTE_HASH_SIZE;
- entry = palette_find(palette, color, hash);
-
- if (!entry && palette->size >= palette->max) {
- return 0;
- }
- if (!entry) {
- VncPaletteEntry *entry;
-
- entry = &palette->pool[palette->size];
- entry->color = color;
- entry->idx = idx;
- QLIST_INSERT_HEAD(&palette->table[hash], entry, next);
- palette->size++;
- }
- return palette->size;
-}
-
-int palette_idx(const VncPalette *palette, uint32_t color)
-{
- VncPaletteEntry *entry;
- unsigned int hash;
-
- hash = palette_hash(color, palette->bpp) % VNC_PALETTE_HASH_SIZE;
- entry = palette_find(palette, color, hash);
- return (entry == NULL ? -1 : entry->idx);
-}
-
-size_t palette_size(const VncPalette *palette)
-{
- return palette->size;
-}
-
-void palette_iter(const VncPalette *palette,
- void (*iter)(int idx, uint32_t color, void *opaque),
- void *opaque)
-{
- int i;
- VncPaletteEntry *entry;
-
- for (i = 0; i < VNC_PALETTE_HASH_SIZE; i++) {
- QLIST_FOREACH(entry, &palette->table[i], next) {
- iter(entry->idx, entry->color, opaque);
- }
- }
-}
-
-uint32_t palette_color(const VncPalette *palette, int idx, bool *found)
-{
- int i;
- VncPaletteEntry *entry;
-
- for (i = 0; i < VNC_PALETTE_HASH_SIZE; i++) {
- QLIST_FOREACH(entry, &palette->table[i], next) {
- if (entry->idx == idx) {
- *found = true;
- return entry->color;
- }
- }
- }
-
- *found = false;
- return -1;
-}
-
-static void palette_fill_cb(int idx, uint32_t color, void *opaque)
-{
- uint32_t *colors = opaque;
-
- colors[idx] = color;
-}
-
-size_t palette_fill(const VncPalette *palette,
- uint32_t colors[VNC_PALETTE_MAX_SIZE])
-{
- palette_iter(palette, palette_fill_cb, colors);
- return palette_size(palette);
-}
diff --git a/qemu/ui/vnc-palette.h b/qemu/ui/vnc-palette.h
deleted file mode 100644
index 1bd4318f5..000000000
--- a/qemu/ui/vnc-palette.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * QEMU VNC display driver: palette hash table
- *
- * From libvncserver/libvncserver/tight.c
- * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved.
- * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
- *
- * Copyright (C) 2010 Corentin Chary <corentin.chary@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef VNC_PALETTE_H
-#define VNC_PALETTE_H
-
-#include "qapi/qmp/qlist.h"
-#include "qemu/queue.h"
-
-#define VNC_PALETTE_HASH_SIZE 256
-#define VNC_PALETTE_MAX_SIZE 256
-
-typedef struct VncPaletteEntry {
- int idx;
- uint32_t color;
- QLIST_ENTRY(VncPaletteEntry) next;
-} VncPaletteEntry;
-
-typedef struct VncPalette {
- VncPaletteEntry pool[VNC_PALETTE_MAX_SIZE];
- size_t size;
- size_t max;
- int bpp;
- QLIST_HEAD(,VncPaletteEntry) table[VNC_PALETTE_HASH_SIZE];
-} VncPalette;
-
-VncPalette *palette_new(size_t max, int bpp);
-void palette_init(VncPalette *palette, size_t max, int bpp);
-void palette_destroy(VncPalette *palette);
-
-int palette_put(VncPalette *palette, uint32_t color);
-int palette_idx(const VncPalette *palette, uint32_t color);
-size_t palette_size(const VncPalette *palette);
-
-void palette_iter(const VncPalette *palette,
- void (*iter)(int idx, uint32_t color, void *opaque),
- void *opaque);
-uint32_t palette_color(const VncPalette *palette, int idx, bool *found);
-size_t palette_fill(const VncPalette *palette,
- uint32_t colors[VNC_PALETTE_MAX_SIZE]);
-
-#endif /* VNC_PALETTE_H */
diff --git a/qemu/ui/vnc-ws.c b/qemu/ui/vnc-ws.c
deleted file mode 100644
index 7c79a4c37..000000000
--- a/qemu/ui/vnc-ws.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * QEMU VNC display driver: Websockets support
- *
- * Copyright (C) 2010 Joel Martin
- * Copyright (C) 2012 Tim Hardeck
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "vnc.h"
-#include "io/channel-websock.h"
-
-static void vncws_tls_handshake_done(Object *source,
- Error *err,
- gpointer user_data)
-{
- VncState *vs = user_data;
-
- if (err) {
- VNC_DEBUG("Handshake failed %s\n", error_get_pretty(err));
- vnc_client_error(vs);
- } else {
- VNC_DEBUG("TLS handshake complete, starting websocket handshake\n");
- vs->ioc_tag = qio_channel_add_watch(
- QIO_CHANNEL(vs->ioc), G_IO_IN, vncws_handshake_io, vs, NULL);
- }
-}
-
-
-gboolean vncws_tls_handshake_io(QIOChannel *ioc G_GNUC_UNUSED,
- GIOCondition condition G_GNUC_UNUSED,
- void *opaque)
-{
- VncState *vs = opaque;
- QIOChannelTLS *tls;
- Error *err = NULL;
-
- VNC_DEBUG("TLS Websocket connection required\n");
- if (vs->ioc_tag) {
- g_source_remove(vs->ioc_tag);
- vs->ioc_tag = 0;
- }
-
- tls = qio_channel_tls_new_server(
- vs->ioc,
- vs->vd->tlscreds,
- vs->vd->tlsaclname,
- &err);
- if (!tls) {
- VNC_DEBUG("Failed to setup TLS %s\n", error_get_pretty(err));
- error_free(err);
- vnc_client_error(vs);
- return TRUE;
- }
-
- VNC_DEBUG("Start TLS WS handshake process\n");
- object_unref(OBJECT(vs->ioc));
- vs->ioc = QIO_CHANNEL(tls);
- vs->tls = qio_channel_tls_get_session(tls);
-
- qio_channel_tls_handshake(tls,
- vncws_tls_handshake_done,
- vs,
- NULL);
-
- return TRUE;
-}
-
-
-static void vncws_handshake_done(Object *source,
- Error *err,
- gpointer user_data)
-{
- VncState *vs = user_data;
-
- if (err) {
- VNC_DEBUG("Websock handshake failed %s\n", error_get_pretty(err));
- vnc_client_error(vs);
- } else {
- VNC_DEBUG("Websock handshake complete, starting VNC protocol\n");
- vnc_init_state(vs);
- vs->ioc_tag = qio_channel_add_watch(
- vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
- }
-}
-
-
-gboolean vncws_handshake_io(QIOChannel *ioc G_GNUC_UNUSED,
- GIOCondition condition G_GNUC_UNUSED,
- void *opaque)
-{
- VncState *vs = opaque;
- QIOChannelWebsock *wioc;
-
- VNC_DEBUG("Websocket negotiate starting\n");
- if (vs->ioc_tag) {
- g_source_remove(vs->ioc_tag);
- vs->ioc_tag = 0;
- }
-
- wioc = qio_channel_websock_new_server(vs->ioc);
-
- object_unref(OBJECT(vs->ioc));
- vs->ioc = QIO_CHANNEL(wioc);
-
- qio_channel_websock_handshake(wioc,
- vncws_handshake_done,
- vs,
- NULL);
-
- return TRUE;
-}
diff --git a/qemu/ui/vnc-ws.h b/qemu/ui/vnc-ws.h
deleted file mode 100644
index 652b6fc39..000000000
--- a/qemu/ui/vnc-ws.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * QEMU VNC display driver: Websockets support
- *
- * Copyright (C) 2010 Joel Martin
- * Copyright (C) 2012 Tim Hardeck
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __QEMU_UI_VNC_WS_H
-#define __QEMU_UI_VNC_WS_H
-
-gboolean vncws_tls_handshake_io(QIOChannel *ioc,
- GIOCondition condition,
- void *opaque);
-gboolean vncws_handshake_io(QIOChannel *ioc,
- GIOCondition condition,
- void *opaque);
-
-#endif /* __QEMU_UI_VNC_WS_H */
diff --git a/qemu/ui/vnc.c b/qemu/ui/vnc.c
deleted file mode 100644
index d2ebf1fb7..000000000
--- a/qemu/ui/vnc.c
+++ /dev/null
@@ -1,3880 +0,0 @@
-/*
- * QEMU VNC display driver
- *
- * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
- * Copyright (C) 2006 Fabrice Bellard
- * Copyright (C) 2009 Red Hat, Inc
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "vnc.h"
-#include "vnc-jobs.h"
-#include "trace.h"
-#include "hw/qdev.h"
-#include "sysemu/sysemu.h"
-#include "qemu/error-report.h"
-#include "qemu/sockets.h"
-#include "qemu/timer.h"
-#include "qemu/acl.h"
-#include "qemu/config-file.h"
-#include "qapi/qmp/qerror.h"
-#include "qapi/qmp/types.h"
-#include "qmp-commands.h"
-#include "ui/input.h"
-#include "qapi-event.h"
-#include "crypto/hash.h"
-#include "crypto/tlscredsanon.h"
-#include "crypto/tlscredsx509.h"
-#include "qom/object_interfaces.h"
-#include "qemu/cutils.h"
-
-#define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
-#define VNC_REFRESH_INTERVAL_INC 50
-#define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
-static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
-static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
-
-#include "vnc_keysym.h"
-#include "crypto/cipher.h"
-
-static QTAILQ_HEAD(, VncDisplay) vnc_displays =
- QTAILQ_HEAD_INITIALIZER(vnc_displays);
-
-static int vnc_cursor_define(VncState *vs);
-static void vnc_release_modifiers(VncState *vs);
-
-static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
-{
-#ifdef _VNC_DEBUG
- static const char *mn[] = {
- [0] = "undefined",
- [VNC_SHARE_MODE_CONNECTING] = "connecting",
- [VNC_SHARE_MODE_SHARED] = "shared",
- [VNC_SHARE_MODE_EXCLUSIVE] = "exclusive",
- [VNC_SHARE_MODE_DISCONNECTED] = "disconnected",
- };
- fprintf(stderr, "%s/%p: %s -> %s\n", __func__,
- vs->ioc, mn[vs->share_mode], mn[mode]);
-#endif
-
- switch (vs->share_mode) {
- case VNC_SHARE_MODE_CONNECTING:
- vs->vd->num_connecting--;
- break;
- case VNC_SHARE_MODE_SHARED:
- vs->vd->num_shared--;
- break;
- case VNC_SHARE_MODE_EXCLUSIVE:
- vs->vd->num_exclusive--;
- break;
- default:
- break;
- }
-
- vs->share_mode = mode;
-
- switch (vs->share_mode) {
- case VNC_SHARE_MODE_CONNECTING:
- vs->vd->num_connecting++;
- break;
- case VNC_SHARE_MODE_SHARED:
- vs->vd->num_shared++;
- break;
- case VNC_SHARE_MODE_EXCLUSIVE:
- vs->vd->num_exclusive++;
- break;
- default:
- break;
- }
-}
-
-
-static void vnc_init_basic_info(SocketAddress *addr,
- VncBasicInfo *info,
- Error **errp)
-{
- switch (addr->type) {
- case SOCKET_ADDRESS_KIND_INET:
- info->host = g_strdup(addr->u.inet.data->host);
- info->service = g_strdup(addr->u.inet.data->port);
- if (addr->u.inet.data->ipv6) {
- info->family = NETWORK_ADDRESS_FAMILY_IPV6;
- } else {
- info->family = NETWORK_ADDRESS_FAMILY_IPV4;
- }
- break;
-
- case SOCKET_ADDRESS_KIND_UNIX:
- info->host = g_strdup("");
- info->service = g_strdup(addr->u.q_unix.data->path);
- info->family = NETWORK_ADDRESS_FAMILY_UNIX;
- break;
-
- default:
- error_setg(errp, "Unsupported socket kind %d",
- addr->type);
- break;
- }
-
- return;
-}
-
-static void vnc_init_basic_info_from_server_addr(QIOChannelSocket *ioc,
- VncBasicInfo *info,
- Error **errp)
-{
- SocketAddress *addr = NULL;
-
- addr = qio_channel_socket_get_local_address(ioc, errp);
- if (!addr) {
- return;
- }
-
- vnc_init_basic_info(addr, info, errp);
- qapi_free_SocketAddress(addr);
-}
-
-static void vnc_init_basic_info_from_remote_addr(QIOChannelSocket *ioc,
- VncBasicInfo *info,
- Error **errp)
-{
- SocketAddress *addr = NULL;
-
- addr = qio_channel_socket_get_remote_address(ioc, errp);
- if (!addr) {
- return;
- }
-
- vnc_init_basic_info(addr, info, errp);
- qapi_free_SocketAddress(addr);
-}
-
-static const char *vnc_auth_name(VncDisplay *vd) {
- switch (vd->auth) {
- case VNC_AUTH_INVALID:
- return "invalid";
- case VNC_AUTH_NONE:
- return "none";
- case VNC_AUTH_VNC:
- return "vnc";
- case VNC_AUTH_RA2:
- return "ra2";
- case VNC_AUTH_RA2NE:
- return "ra2ne";
- case VNC_AUTH_TIGHT:
- return "tight";
- case VNC_AUTH_ULTRA:
- return "ultra";
- case VNC_AUTH_TLS:
- return "tls";
- case VNC_AUTH_VENCRYPT:
- switch (vd->subauth) {
- case VNC_AUTH_VENCRYPT_PLAIN:
- return "vencrypt+plain";
- case VNC_AUTH_VENCRYPT_TLSNONE:
- return "vencrypt+tls+none";
- case VNC_AUTH_VENCRYPT_TLSVNC:
- return "vencrypt+tls+vnc";
- case VNC_AUTH_VENCRYPT_TLSPLAIN:
- return "vencrypt+tls+plain";
- case VNC_AUTH_VENCRYPT_X509NONE:
- return "vencrypt+x509+none";
- case VNC_AUTH_VENCRYPT_X509VNC:
- return "vencrypt+x509+vnc";
- case VNC_AUTH_VENCRYPT_X509PLAIN:
- return "vencrypt+x509+plain";
- case VNC_AUTH_VENCRYPT_TLSSASL:
- return "vencrypt+tls+sasl";
- case VNC_AUTH_VENCRYPT_X509SASL:
- return "vencrypt+x509+sasl";
- default:
- return "vencrypt";
- }
- case VNC_AUTH_SASL:
- return "sasl";
- }
- return "unknown";
-}
-
-static VncServerInfo *vnc_server_info_get(VncDisplay *vd)
-{
- VncServerInfo *info;
- Error *err = NULL;
-
- info = g_malloc(sizeof(*info));
- vnc_init_basic_info_from_server_addr(vd->lsock,
- qapi_VncServerInfo_base(info), &err);
- info->has_auth = true;
- info->auth = g_strdup(vnc_auth_name(vd));
- if (err) {
- qapi_free_VncServerInfo(info);
- info = NULL;
- error_free(err);
- }
- return info;
-}
-
-static void vnc_client_cache_auth(VncState *client)
-{
- if (!client->info) {
- return;
- }
-
- if (client->tls) {
- client->info->x509_dname =
- qcrypto_tls_session_get_peer_name(client->tls);
- client->info->has_x509_dname =
- client->info->x509_dname != NULL;
- }
-#ifdef CONFIG_VNC_SASL
- if (client->sasl.conn &&
- client->sasl.username) {
- client->info->has_sasl_username = true;
- client->info->sasl_username = g_strdup(client->sasl.username);
- }
-#endif
-}
-
-static void vnc_client_cache_addr(VncState *client)
-{
- Error *err = NULL;
-
- client->info = g_malloc0(sizeof(*client->info));
- vnc_init_basic_info_from_remote_addr(client->sioc,
- qapi_VncClientInfo_base(client->info),
- &err);
- if (err) {
- qapi_free_VncClientInfo(client->info);
- client->info = NULL;
- error_free(err);
- }
-}
-
-static void vnc_qmp_event(VncState *vs, QAPIEvent event)
-{
- VncServerInfo *si;
-
- if (!vs->info) {
- return;
- }
-
- si = vnc_server_info_get(vs->vd);
- if (!si) {
- return;
- }
-
- switch (event) {
- case QAPI_EVENT_VNC_CONNECTED:
- qapi_event_send_vnc_connected(si, qapi_VncClientInfo_base(vs->info),
- &error_abort);
- break;
- case QAPI_EVENT_VNC_INITIALIZED:
- qapi_event_send_vnc_initialized(si, vs->info, &error_abort);
- break;
- case QAPI_EVENT_VNC_DISCONNECTED:
- qapi_event_send_vnc_disconnected(si, vs->info, &error_abort);
- break;
- default:
- break;
- }
-
- qapi_free_VncServerInfo(si);
-}
-
-static VncClientInfo *qmp_query_vnc_client(const VncState *client)
-{
- VncClientInfo *info;
- Error *err = NULL;
-
- info = g_malloc0(sizeof(*info));
-
- vnc_init_basic_info_from_remote_addr(client->sioc,
- qapi_VncClientInfo_base(info),
- &err);
- if (err) {
- error_free(err);
- qapi_free_VncClientInfo(info);
- return NULL;
- }
-
- info->websocket = client->websocket;
-
- if (client->tls) {
- info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);
- info->has_x509_dname = info->x509_dname != NULL;
- }
-#ifdef CONFIG_VNC_SASL
- if (client->sasl.conn && client->sasl.username) {
- info->has_sasl_username = true;
- info->sasl_username = g_strdup(client->sasl.username);
- }
-#endif
-
- return info;
-}
-
-static VncDisplay *vnc_display_find(const char *id)
-{
- VncDisplay *vd;
-
- if (id == NULL) {
- return QTAILQ_FIRST(&vnc_displays);
- }
- QTAILQ_FOREACH(vd, &vnc_displays, next) {
- if (strcmp(id, vd->id) == 0) {
- return vd;
- }
- }
- return NULL;
-}
-
-static VncClientInfoList *qmp_query_client_list(VncDisplay *vd)
-{
- VncClientInfoList *cinfo, *prev = NULL;
- VncState *client;
-
- QTAILQ_FOREACH(client, &vd->clients, next) {
- cinfo = g_new0(VncClientInfoList, 1);
- cinfo->value = qmp_query_vnc_client(client);
- cinfo->next = prev;
- prev = cinfo;
- }
- return prev;
-}
-
-VncInfo *qmp_query_vnc(Error **errp)
-{
- VncInfo *info = g_malloc0(sizeof(*info));
- VncDisplay *vd = vnc_display_find(NULL);
- SocketAddress *addr = NULL;
-
- if (vd == NULL || !vd->enabled) {
- info->enabled = false;
- } else {
- info->enabled = true;
-
- /* for compatibility with the original command */
- info->has_clients = true;
- info->clients = qmp_query_client_list(vd);
-
- if (vd->lsock == NULL) {
- return info;
- }
-
- addr = qio_channel_socket_get_local_address(vd->lsock, errp);
- if (!addr) {
- goto out_error;
- }
-
- switch (addr->type) {
- case SOCKET_ADDRESS_KIND_INET:
- info->host = g_strdup(addr->u.inet.data->host);
- info->service = g_strdup(addr->u.inet.data->port);
- if (addr->u.inet.data->ipv6) {
- info->family = NETWORK_ADDRESS_FAMILY_IPV6;
- } else {
- info->family = NETWORK_ADDRESS_FAMILY_IPV4;
- }
- break;
-
- case SOCKET_ADDRESS_KIND_UNIX:
- info->host = g_strdup("");
- info->service = g_strdup(addr->u.q_unix.data->path);
- info->family = NETWORK_ADDRESS_FAMILY_UNIX;
- break;
-
- default:
- error_setg(errp, "Unsupported socket kind %d",
- addr->type);
- goto out_error;
- }
-
- info->has_host = true;
- info->has_service = true;
- info->has_family = true;
-
- info->has_auth = true;
- info->auth = g_strdup(vnc_auth_name(vd));
- }
-
- qapi_free_SocketAddress(addr);
- return info;
-
-out_error:
- qapi_free_SocketAddress(addr);
- qapi_free_VncInfo(info);
- return NULL;
-}
-
-static VncBasicInfoList *qmp_query_server_entry(QIOChannelSocket *ioc,
- bool websocket,
- VncBasicInfoList *prev)
-{
- VncBasicInfoList *list;
- VncBasicInfo *info;
- Error *err = NULL;
- SocketAddress *addr;
-
- addr = qio_channel_socket_get_local_address(ioc, &err);
- if (!addr) {
- error_free(err);
- return prev;
- }
-
- info = g_new0(VncBasicInfo, 1);
- vnc_init_basic_info(addr, info, &err);
- qapi_free_SocketAddress(addr);
- if (err) {
- qapi_free_VncBasicInfo(info);
- error_free(err);
- return prev;
- }
- info->websocket = websocket;
-
- list = g_new0(VncBasicInfoList, 1);
- list->value = info;
- list->next = prev;
- return list;
-}
-
-static void qmp_query_auth(VncDisplay *vd, VncInfo2 *info)
-{
- switch (vd->auth) {
- case VNC_AUTH_VNC:
- info->auth = VNC_PRIMARY_AUTH_VNC;
- break;
- case VNC_AUTH_RA2:
- info->auth = VNC_PRIMARY_AUTH_RA2;
- break;
- case VNC_AUTH_RA2NE:
- info->auth = VNC_PRIMARY_AUTH_RA2NE;
- break;
- case VNC_AUTH_TIGHT:
- info->auth = VNC_PRIMARY_AUTH_TIGHT;
- break;
- case VNC_AUTH_ULTRA:
- info->auth = VNC_PRIMARY_AUTH_ULTRA;
- break;
- case VNC_AUTH_TLS:
- info->auth = VNC_PRIMARY_AUTH_TLS;
- break;
- case VNC_AUTH_VENCRYPT:
- info->auth = VNC_PRIMARY_AUTH_VENCRYPT;
- info->has_vencrypt = true;
- switch (vd->subauth) {
- case VNC_AUTH_VENCRYPT_PLAIN:
- info->vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;
- break;
- case VNC_AUTH_VENCRYPT_TLSNONE:
- info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;
- break;
- case VNC_AUTH_VENCRYPT_TLSVNC:
- info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;
- break;
- case VNC_AUTH_VENCRYPT_TLSPLAIN:
- info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;
- break;
- case VNC_AUTH_VENCRYPT_X509NONE:
- info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;
- break;
- case VNC_AUTH_VENCRYPT_X509VNC:
- info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;
- break;
- case VNC_AUTH_VENCRYPT_X509PLAIN:
- info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;
- break;
- case VNC_AUTH_VENCRYPT_TLSSASL:
- info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;
- break;
- case VNC_AUTH_VENCRYPT_X509SASL:
- info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;
- break;
- default:
- info->has_vencrypt = false;
- break;
- }
- break;
- case VNC_AUTH_SASL:
- info->auth = VNC_PRIMARY_AUTH_SASL;
- break;
- case VNC_AUTH_NONE:
- default:
- info->auth = VNC_PRIMARY_AUTH_NONE;
- break;
- }
-}
-
-VncInfo2List *qmp_query_vnc_servers(Error **errp)
-{
- VncInfo2List *item, *prev = NULL;
- VncInfo2 *info;
- VncDisplay *vd;
- DeviceState *dev;
-
- QTAILQ_FOREACH(vd, &vnc_displays, next) {
- info = g_new0(VncInfo2, 1);
- info->id = g_strdup(vd->id);
- info->clients = qmp_query_client_list(vd);
- qmp_query_auth(vd, info);
- if (vd->dcl.con) {
- dev = DEVICE(object_property_get_link(OBJECT(vd->dcl.con),
- "device", NULL));
- info->has_display = true;
- info->display = g_strdup(dev->id);
- }
- if (vd->lsock != NULL) {
- info->server = qmp_query_server_entry(
- vd->lsock, false, info->server);
- }
- if (vd->lwebsock != NULL) {
- info->server = qmp_query_server_entry(
- vd->lwebsock, true, info->server);
- }
-
- item = g_new0(VncInfo2List, 1);
- item->value = info;
- item->next = prev;
- prev = item;
- }
- return prev;
-}
-
-/* TODO
- 1) Get the queue working for IO.
- 2) there is some weirdness when using the -S option (the screen is grey
- and not totally invalidated
- 3) resolutions > 1024
-*/
-
-static int vnc_update_client(VncState *vs, int has_dirty, bool sync);
-static void vnc_disconnect_start(VncState *vs);
-
-static void vnc_colordepth(VncState *vs);
-static void framebuffer_update_request(VncState *vs, int incremental,
- int x_position, int y_position,
- int w, int h);
-static void vnc_refresh(DisplayChangeListener *dcl);
-static int vnc_refresh_server_surface(VncDisplay *vd);
-
-static int vnc_width(VncDisplay *vd)
-{
- return MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds),
- VNC_DIRTY_PIXELS_PER_BIT));
-}
-
-static int vnc_height(VncDisplay *vd)
-{
- return MIN(VNC_MAX_HEIGHT, surface_height(vd->ds));
-}
-
-static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
- VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT),
- VncDisplay *vd,
- int x, int y, int w, int h)
-{
- int width = vnc_width(vd);
- int height = vnc_height(vd);
-
- /* this is needed this to ensure we updated all affected
- * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */
- w += (x % VNC_DIRTY_PIXELS_PER_BIT);
- x -= (x % VNC_DIRTY_PIXELS_PER_BIT);
-
- x = MIN(x, width);
- y = MIN(y, height);
- w = MIN(x + w, width) - x;
- h = MIN(y + h, height);
-
- for (; y < h; y++) {
- bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT,
- DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));
- }
-}
-
-static void vnc_dpy_update(DisplayChangeListener *dcl,
- int x, int y, int w, int h)
-{
- VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
- struct VncSurface *s = &vd->guest;
-
- vnc_set_area_dirty(s->dirty, vd, x, y, w, h);
-}
-
-void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
- int32_t encoding)
-{
- vnc_write_u16(vs, x);
- vnc_write_u16(vs, y);
- vnc_write_u16(vs, w);
- vnc_write_u16(vs, h);
-
- vnc_write_s32(vs, encoding);
-}
-
-
-static void vnc_desktop_resize(VncState *vs)
-{
- if (vs->ioc == NULL || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) {
- return;
- }
- if (vs->client_width == pixman_image_get_width(vs->vd->server) &&
- vs->client_height == pixman_image_get_height(vs->vd->server)) {
- return;
- }
- vs->client_width = pixman_image_get_width(vs->vd->server);
- vs->client_height = pixman_image_get_height(vs->vd->server);
- vnc_lock_output(vs);
- vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
- vnc_write_u8(vs, 0);
- vnc_write_u16(vs, 1); /* number of rects */
- vnc_framebuffer_update(vs, 0, 0, vs->client_width, vs->client_height,
- VNC_ENCODING_DESKTOPRESIZE);
- vnc_unlock_output(vs);
- vnc_flush(vs);
-}
-
-static void vnc_abort_display_jobs(VncDisplay *vd)
-{
- VncState *vs;
-
- QTAILQ_FOREACH(vs, &vd->clients, next) {
- vnc_lock_output(vs);
- vs->abort = true;
- vnc_unlock_output(vs);
- }
- QTAILQ_FOREACH(vs, &vd->clients, next) {
- vnc_jobs_join(vs);
- }
- QTAILQ_FOREACH(vs, &vd->clients, next) {
- vnc_lock_output(vs);
- vs->abort = false;
- vnc_unlock_output(vs);
- }
-}
-
-int vnc_server_fb_stride(VncDisplay *vd)
-{
- return pixman_image_get_stride(vd->server);
-}
-
-void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
-{
- uint8_t *ptr;
-
- ptr = (uint8_t *)pixman_image_get_data(vd->server);
- ptr += y * vnc_server_fb_stride(vd);
- ptr += x * VNC_SERVER_FB_BYTES;
- return ptr;
-}
-
-static void vnc_update_server_surface(VncDisplay *vd)
-{
- qemu_pixman_image_unref(vd->server);
- vd->server = NULL;
-
- if (QTAILQ_EMPTY(&vd->clients)) {
- return;
- }
-
- vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
- vnc_width(vd),
- vnc_height(vd),
- NULL, 0);
-}
-
-static void vnc_dpy_switch(DisplayChangeListener *dcl,
- DisplaySurface *surface)
-{
- VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
- VncState *vs;
- int width, height;
-
- vnc_abort_display_jobs(vd);
- vd->ds = surface;
-
- /* server surface */
- vnc_update_server_surface(vd);
-
- /* guest surface */
- qemu_pixman_image_unref(vd->guest.fb);
- vd->guest.fb = pixman_image_ref(surface->image);
- vd->guest.format = surface->format;
- width = vnc_width(vd);
- height = vnc_height(vd);
- memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty));
- vnc_set_area_dirty(vd->guest.dirty, vd, 0, 0,
- width, height);
-
- QTAILQ_FOREACH(vs, &vd->clients, next) {
- vnc_colordepth(vs);
- vnc_desktop_resize(vs);
- if (vs->vd->cursor) {
- vnc_cursor_define(vs);
- }
- memset(vs->dirty, 0x00, sizeof(vs->dirty));
- vnc_set_area_dirty(vs->dirty, vd, 0, 0,
- width, height);
- }
-}
-
-/* fastest code */
-static void vnc_write_pixels_copy(VncState *vs,
- void *pixels, int size)
-{
- vnc_write(vs, pixels, size);
-}
-
-/* slowest but generic code. */
-void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
-{
- uint8_t r, g, b;
-
-#if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
- r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
- g = (((v & 0x0000ff00) >> 8) << vs->client_pf.gbits) >> 8;
- b = (((v & 0x000000ff) >> 0) << vs->client_pf.bbits) >> 8;
-#else
-# error need some bits here if you change VNC_SERVER_FB_FORMAT
-#endif
- v = (r << vs->client_pf.rshift) |
- (g << vs->client_pf.gshift) |
- (b << vs->client_pf.bshift);
- switch (vs->client_pf.bytes_per_pixel) {
- case 1:
- buf[0] = v;
- break;
- case 2:
- if (vs->client_be) {
- buf[0] = v >> 8;
- buf[1] = v;
- } else {
- buf[1] = v >> 8;
- buf[0] = v;
- }
- break;
- default:
- case 4:
- if (vs->client_be) {
- buf[0] = v >> 24;
- buf[1] = v >> 16;
- buf[2] = v >> 8;
- buf[3] = v;
- } else {
- buf[3] = v >> 24;
- buf[2] = v >> 16;
- buf[1] = v >> 8;
- buf[0] = v;
- }
- break;
- }
-}
-
-static void vnc_write_pixels_generic(VncState *vs,
- void *pixels1, int size)
-{
- uint8_t buf[4];
-
- if (VNC_SERVER_FB_BYTES == 4) {
- uint32_t *pixels = pixels1;
- int n, i;
- n = size >> 2;
- for (i = 0; i < n; i++) {
- vnc_convert_pixel(vs, buf, pixels[i]);
- vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
- }
- }
-}
-
-int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
-{
- int i;
- uint8_t *row;
- VncDisplay *vd = vs->vd;
-
- row = vnc_server_fb_ptr(vd, x, y);
- for (i = 0; i < h; i++) {
- vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
- row += vnc_server_fb_stride(vd);
- }
- return 1;
-}
-
-int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
-{
- int n = 0;
- bool encode_raw = false;
- size_t saved_offs = vs->output.offset;
-
- switch(vs->vnc_encoding) {
- case VNC_ENCODING_ZLIB:
- n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
- break;
- case VNC_ENCODING_HEXTILE:
- vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
- n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
- break;
- case VNC_ENCODING_TIGHT:
- n = vnc_tight_send_framebuffer_update(vs, x, y, w, h);
- break;
- case VNC_ENCODING_TIGHT_PNG:
- n = vnc_tight_png_send_framebuffer_update(vs, x, y, w, h);
- break;
- case VNC_ENCODING_ZRLE:
- n = vnc_zrle_send_framebuffer_update(vs, x, y, w, h);
- break;
- case VNC_ENCODING_ZYWRLE:
- n = vnc_zywrle_send_framebuffer_update(vs, x, y, w, h);
- break;
- default:
- encode_raw = true;
- break;
- }
-
- /* If the client has the same pixel format as our internal buffer and
- * a RAW encoding would need less space fall back to RAW encoding to
- * save bandwidth and processing power in the client. */
- if (!encode_raw && vs->write_pixels == vnc_write_pixels_copy &&
- 12 + h * w * VNC_SERVER_FB_BYTES <= (vs->output.offset - saved_offs)) {
- vs->output.offset = saved_offs;
- encode_raw = true;
- }
-
- if (encode_raw) {
- vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
- n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
- }
-
- return n;
-}
-
-static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
-{
- /* send bitblit op to the vnc client */
- vnc_lock_output(vs);
- vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
- vnc_write_u8(vs, 0);
- vnc_write_u16(vs, 1); /* number of rects */
- vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
- vnc_write_u16(vs, src_x);
- vnc_write_u16(vs, src_y);
- vnc_unlock_output(vs);
- vnc_flush(vs);
-}
-
-static void vnc_dpy_copy(DisplayChangeListener *dcl,
- int src_x, int src_y,
- int dst_x, int dst_y, int w, int h)
-{
- VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
- VncState *vs, *vn;
- uint8_t *src_row;
- uint8_t *dst_row;
- int i, x, y, pitch, inc, w_lim, s;
- int cmp_bytes;
-
- if (!vd->server) {
- /* no client connected */
- return;
- }
-
- vnc_refresh_server_surface(vd);
- QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
- if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
- vs->force_update = 1;
- vnc_update_client(vs, 1, true);
- /* vs might be free()ed here */
- }
- }
-
- /* do bitblit op on the local surface too */
- pitch = vnc_server_fb_stride(vd);
- src_row = vnc_server_fb_ptr(vd, src_x, src_y);
- dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y);
- y = dst_y;
- inc = 1;
- if (dst_y > src_y) {
- /* copy backwards */
- src_row += pitch * (h-1);
- dst_row += pitch * (h-1);
- pitch = -pitch;
- y = dst_y + h - 1;
- inc = -1;
- }
- w_lim = w - (VNC_DIRTY_PIXELS_PER_BIT - (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
- if (w_lim < 0) {
- w_lim = w;
- } else {
- w_lim = w - (w_lim % VNC_DIRTY_PIXELS_PER_BIT);
- }
- for (i = 0; i < h; i++) {
- for (x = 0; x <= w_lim;
- x += s, src_row += cmp_bytes, dst_row += cmp_bytes) {
- if (x == w_lim) {
- if ((s = w - w_lim) == 0)
- break;
- } else if (!x) {
- s = (VNC_DIRTY_PIXELS_PER_BIT -
- (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
- s = MIN(s, w_lim);
- } else {
- s = VNC_DIRTY_PIXELS_PER_BIT;
- }
- cmp_bytes = s * VNC_SERVER_FB_BYTES;
- if (memcmp(src_row, dst_row, cmp_bytes) == 0)
- continue;
- memmove(dst_row, src_row, cmp_bytes);
- QTAILQ_FOREACH(vs, &vd->clients, next) {
- if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
- set_bit(((x + dst_x) / VNC_DIRTY_PIXELS_PER_BIT),
- vs->dirty[y]);
- }
- }
- }
- src_row += pitch - w * VNC_SERVER_FB_BYTES;
- dst_row += pitch - w * VNC_SERVER_FB_BYTES;
- y += inc;
- }
-
- QTAILQ_FOREACH(vs, &vd->clients, next) {
- if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
- vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
- }
- }
-}
-
-static void vnc_mouse_set(DisplayChangeListener *dcl,
- int x, int y, int visible)
-{
- /* can we ask the client(s) to move the pointer ??? */
-}
-
-static int vnc_cursor_define(VncState *vs)
-{
- QEMUCursor *c = vs->vd->cursor;
- int isize;
-
- if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
- vnc_lock_output(vs);
- vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
- vnc_write_u8(vs, 0); /* padding */
- vnc_write_u16(vs, 1); /* # of rects */
- vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
- VNC_ENCODING_RICH_CURSOR);
- isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
- vnc_write_pixels_generic(vs, c->data, isize);
- vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
- vnc_unlock_output(vs);
- return 0;
- }
- return -1;
-}
-
-static void vnc_dpy_cursor_define(DisplayChangeListener *dcl,
- QEMUCursor *c)
-{
- VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
- VncState *vs;
-
- cursor_put(vd->cursor);
- g_free(vd->cursor_mask);
-
- vd->cursor = c;
- cursor_get(vd->cursor);
- vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
- vd->cursor_mask = g_malloc0(vd->cursor_msize);
- cursor_get_mono_mask(c, 0, vd->cursor_mask);
-
- QTAILQ_FOREACH(vs, &vd->clients, next) {
- vnc_cursor_define(vs);
- }
-}
-
-static int find_and_clear_dirty_height(VncState *vs,
- int y, int last_x, int x, int height)
-{
- int h;
-
- for (h = 1; h < (height - y); h++) {
- if (!test_bit(last_x, vs->dirty[y + h])) {
- break;
- }
- bitmap_clear(vs->dirty[y + h], last_x, x - last_x);
- }
-
- return h;
-}
-
-static int vnc_update_client(VncState *vs, int has_dirty, bool sync)
-{
- vs->has_dirty += has_dirty;
- if (vs->need_update && vs->ioc != NULL) {
- VncDisplay *vd = vs->vd;
- VncJob *job;
- int y;
- int height, width;
- int n = 0;
-
- if (vs->output.offset && !vs->audio_cap && !vs->force_update)
- /* kernel send buffers are full -> drop frames to throttle */
- return 0;
-
- if (!vs->has_dirty && !vs->audio_cap && !vs->force_update)
- return 0;
-
- /*
- * Send screen updates to the vnc client using the server
- * surface and server dirty map. guest surface updates
- * happening in parallel don't disturb us, the next pass will
- * send them to the client.
- */
- job = vnc_job_new(vs);
-
- height = pixman_image_get_height(vd->server);
- width = pixman_image_get_width(vd->server);
-
- y = 0;
- for (;;) {
- int x, h;
- unsigned long x2;
- unsigned long offset = find_next_bit((unsigned long *) &vs->dirty,
- height * VNC_DIRTY_BPL(vs),
- y * VNC_DIRTY_BPL(vs));
- if (offset == height * VNC_DIRTY_BPL(vs)) {
- /* no more dirty bits */
- break;
- }
- y = offset / VNC_DIRTY_BPL(vs);
- x = offset % VNC_DIRTY_BPL(vs);
- x2 = find_next_zero_bit((unsigned long *) &vs->dirty[y],
- VNC_DIRTY_BPL(vs), x);
- bitmap_clear(vs->dirty[y], x, x2 - x);
- h = find_and_clear_dirty_height(vs, y, x, x2, height);
- x2 = MIN(x2, width / VNC_DIRTY_PIXELS_PER_BIT);
- if (x2 > x) {
- n += vnc_job_add_rect(job, x * VNC_DIRTY_PIXELS_PER_BIT, y,
- (x2 - x) * VNC_DIRTY_PIXELS_PER_BIT, h);
- }
- if (!x && x2 == width / VNC_DIRTY_PIXELS_PER_BIT) {
- y += h;
- if (y == height) {
- break;
- }
- }
- }
-
- vnc_job_push(job);
- if (sync) {
- vnc_jobs_join(vs);
- }
- vs->force_update = 0;
- vs->has_dirty = 0;
- return n;
- }
-
- if (vs->disconnecting) {
- vnc_disconnect_finish(vs);
- } else if (sync) {
- vnc_jobs_join(vs);
- }
-
- return 0;
-}
-
-/* audio */
-static void audio_capture_notify(void *opaque, audcnotification_e cmd)
-{
- VncState *vs = opaque;
-
- switch (cmd) {
- case AUD_CNOTIFY_DISABLE:
- vnc_lock_output(vs);
- vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
- vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
- vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_END);
- vnc_unlock_output(vs);
- vnc_flush(vs);
- break;
-
- case AUD_CNOTIFY_ENABLE:
- vnc_lock_output(vs);
- vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
- vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
- vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_BEGIN);
- vnc_unlock_output(vs);
- vnc_flush(vs);
- break;
- }
-}
-
-static void audio_capture_destroy(void *opaque)
-{
-}
-
-static void audio_capture(void *opaque, void *buf, int size)
-{
- VncState *vs = opaque;
-
- vnc_lock_output(vs);
- vnc_write_u8(vs, VNC_MSG_SERVER_QEMU);
- vnc_write_u8(vs, VNC_MSG_SERVER_QEMU_AUDIO);
- vnc_write_u16(vs, VNC_MSG_SERVER_QEMU_AUDIO_DATA);
- vnc_write_u32(vs, size);
- vnc_write(vs, buf, size);
- vnc_unlock_output(vs);
- vnc_flush(vs);
-}
-
-static void audio_add(VncState *vs)
-{
- struct audio_capture_ops ops;
-
- if (vs->audio_cap) {
- error_report("audio already running");
- return;
- }
-
- ops.notify = audio_capture_notify;
- ops.destroy = audio_capture_destroy;
- ops.capture = audio_capture;
-
- vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
- if (!vs->audio_cap) {
- error_report("Failed to add audio capture");
- }
-}
-
-static void audio_del(VncState *vs)
-{
- if (vs->audio_cap) {
- AUD_del_capture(vs->audio_cap, vs);
- vs->audio_cap = NULL;
- }
-}
-
-static void vnc_disconnect_start(VncState *vs)
-{
- if (vs->disconnecting) {
- return;
- }
- vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED);
- if (vs->ioc_tag) {
- g_source_remove(vs->ioc_tag);
- }
- qio_channel_close(vs->ioc, NULL);
- vs->disconnecting = TRUE;
-}
-
-void vnc_disconnect_finish(VncState *vs)
-{
- int i;
-
- vnc_jobs_join(vs); /* Wait encoding jobs */
-
- vnc_lock_output(vs);
- vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
-
- buffer_free(&vs->input);
- buffer_free(&vs->output);
-
- qapi_free_VncClientInfo(vs->info);
-
- vnc_zlib_clear(vs);
- vnc_tight_clear(vs);
- vnc_zrle_clear(vs);
-
-#ifdef CONFIG_VNC_SASL
- vnc_sasl_client_cleanup(vs);
-#endif /* CONFIG_VNC_SASL */
- audio_del(vs);
- vnc_release_modifiers(vs);
-
- if (vs->initialized) {
- QTAILQ_REMOVE(&vs->vd->clients, vs, next);
- qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
- if (QTAILQ_EMPTY(&vs->vd->clients)) {
- /* last client gone */
- vnc_update_server_surface(vs->vd);
- }
- }
-
- if (vs->vd->lock_key_sync)
- qemu_remove_led_event_handler(vs->led);
- vnc_unlock_output(vs);
-
- qemu_mutex_destroy(&vs->output_mutex);
- if (vs->bh != NULL) {
- qemu_bh_delete(vs->bh);
- }
- buffer_free(&vs->jobs_buffer);
-
- for (i = 0; i < VNC_STAT_ROWS; ++i) {
- g_free(vs->lossy_rect[i]);
- }
- g_free(vs->lossy_rect);
-
- object_unref(OBJECT(vs->ioc));
- vs->ioc = NULL;
- object_unref(OBJECT(vs->sioc));
- vs->sioc = NULL;
- g_free(vs);
-}
-
-ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
-{
- if (ret <= 0) {
- if (ret == 0) {
- VNC_DEBUG("Closing down client sock: EOF\n");
- } else if (ret != QIO_CHANNEL_ERR_BLOCK) {
- VNC_DEBUG("Closing down client sock: ret %d (%s)\n",
- ret, errp ? error_get_pretty(*errp) : "Unknown");
- }
-
- vnc_disconnect_start(vs);
- if (errp) {
- error_free(*errp);
- *errp = NULL;
- }
- return 0;
- }
- return ret;
-}
-
-
-void vnc_client_error(VncState *vs)
-{
- VNC_DEBUG("Closing down client sock: protocol error\n");
- vnc_disconnect_start(vs);
-}
-
-
-/*
- * Called to write a chunk of data to the client socket. The data may
- * be the raw data, or may have already been encoded by SASL.
- * The data will be written either straight onto the socket, or
- * written via the GNUTLS wrappers, if TLS/SSL encryption is enabled
- *
- * NB, it is theoretically possible to have 2 layers of encryption,
- * both SASL, and this TLS layer. It is highly unlikely in practice
- * though, since SASL encryption will typically be a no-op if TLS
- * is active
- *
- * Returns the number of bytes written, which may be less than
- * the requested 'datalen' if the socket would block. Returns
- * -1 on error, and disconnects the client socket.
- */
-ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
-{
- Error *err = NULL;
- ssize_t ret;
- ret = qio_channel_write(
- vs->ioc, (const char *)data, datalen, &err);
- VNC_DEBUG("Wrote wire %p %zd -> %ld\n", data, datalen, ret);
- return vnc_client_io_error(vs, ret, &err);
-}
-
-
-/*
- * Called to write buffered data to the client socket, when not
- * using any SASL SSF encryption layers. Will write as much data
- * as possible without blocking. If all buffered data is written,
- * will switch the FD poll() handler back to read monitoring.
- *
- * Returns the number of bytes written, which may be less than
- * the buffered output data if the socket would block. Returns
- * -1 on error, and disconnects the client socket.
- */
-static ssize_t vnc_client_write_plain(VncState *vs)
-{
- ssize_t ret;
-
-#ifdef CONFIG_VNC_SASL
- VNC_DEBUG("Write Plain: Pending output %p size %zd offset %zd. Wait SSF %d\n",
- vs->output.buffer, vs->output.capacity, vs->output.offset,
- vs->sasl.waitWriteSSF);
-
- if (vs->sasl.conn &&
- vs->sasl.runSSF &&
- vs->sasl.waitWriteSSF) {
- ret = vnc_client_write_buf(vs, vs->output.buffer, vs->sasl.waitWriteSSF);
- if (ret)
- vs->sasl.waitWriteSSF -= ret;
- } else
-#endif /* CONFIG_VNC_SASL */
- ret = vnc_client_write_buf(vs, vs->output.buffer, vs->output.offset);
- if (!ret)
- return 0;
-
- buffer_advance(&vs->output, ret);
-
- if (vs->output.offset == 0) {
- if (vs->ioc_tag) {
- g_source_remove(vs->ioc_tag);
- }
- vs->ioc_tag = qio_channel_add_watch(
- vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
- }
-
- return ret;
-}
-
-
-/*
- * First function called whenever there is data to be written to
- * the client socket. Will delegate actual work according to whether
- * SASL SSF layers are enabled (thus requiring encryption calls)
- */
-static void vnc_client_write_locked(VncState *vs)
-{
-#ifdef CONFIG_VNC_SASL
- if (vs->sasl.conn &&
- vs->sasl.runSSF &&
- !vs->sasl.waitWriteSSF) {
- vnc_client_write_sasl(vs);
- } else
-#endif /* CONFIG_VNC_SASL */
- {
- vnc_client_write_plain(vs);
- }
-}
-
-static void vnc_client_write(VncState *vs)
-{
-
- vnc_lock_output(vs);
- if (vs->output.offset) {
- vnc_client_write_locked(vs);
- } else if (vs->ioc != NULL) {
- if (vs->ioc_tag) {
- g_source_remove(vs->ioc_tag);
- }
- vs->ioc_tag = qio_channel_add_watch(
- vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
- }
- vnc_unlock_output(vs);
-}
-
-void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting)
-{
- vs->read_handler = func;
- vs->read_handler_expect = expecting;
-}
-
-
-/*
- * Called to read a chunk of data from the client socket. The data may
- * be the raw data, or may need to be further decoded by SASL.
- * The data will be read either straight from to the socket, or
- * read via the GNUTLS wrappers, if TLS/SSL encryption is enabled
- *
- * NB, it is theoretically possible to have 2 layers of encryption,
- * both SASL, and this TLS layer. It is highly unlikely in practice
- * though, since SASL encryption will typically be a no-op if TLS
- * is active
- *
- * Returns the number of bytes read, which may be less than
- * the requested 'datalen' if the socket would block. Returns
- * -1 on error, and disconnects the client socket.
- */
-ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
-{
- ssize_t ret;
- Error *err = NULL;
- ret = qio_channel_read(
- vs->ioc, (char *)data, datalen, &err);
- VNC_DEBUG("Read wire %p %zd -> %ld\n", data, datalen, ret);
- return vnc_client_io_error(vs, ret, &err);
-}
-
-
-/*
- * Called to read data from the client socket to the input buffer,
- * when not using any SASL SSF encryption layers. Will read as much
- * data as possible without blocking.
- *
- * Returns the number of bytes read. Returns -1 on error, and
- * disconnects the client socket.
- */
-static ssize_t vnc_client_read_plain(VncState *vs)
-{
- ssize_t ret;
- VNC_DEBUG("Read plain %p size %zd offset %zd\n",
- vs->input.buffer, vs->input.capacity, vs->input.offset);
- buffer_reserve(&vs->input, 4096);
- ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
- if (!ret)
- return 0;
- vs->input.offset += ret;
- return ret;
-}
-
-static void vnc_jobs_bh(void *opaque)
-{
- VncState *vs = opaque;
-
- vnc_jobs_consume_buffer(vs);
-}
-
-/*
- * First function called whenever there is more data to be read from
- * the client socket. Will delegate actual work according to whether
- * SASL SSF layers are enabled (thus requiring decryption calls)
- */
-static void vnc_client_read(VncState *vs)
-{
- ssize_t ret;
-
-#ifdef CONFIG_VNC_SASL
- if (vs->sasl.conn && vs->sasl.runSSF)
- ret = vnc_client_read_sasl(vs);
- else
-#endif /* CONFIG_VNC_SASL */
- ret = vnc_client_read_plain(vs);
- if (!ret) {
- if (vs->disconnecting) {
- vnc_disconnect_finish(vs);
- }
- return;
- }
-
- while (vs->read_handler && vs->input.offset >= vs->read_handler_expect) {
- size_t len = vs->read_handler_expect;
- int ret;
-
- ret = vs->read_handler(vs, vs->input.buffer, len);
- if (vs->disconnecting) {
- vnc_disconnect_finish(vs);
- return;
- }
-
- if (!ret) {
- buffer_advance(&vs->input, len);
- } else {
- vs->read_handler_expect = ret;
- }
- }
-}
-
-gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,
- GIOCondition condition, void *opaque)
-{
- VncState *vs = opaque;
- if (condition & G_IO_IN) {
- vnc_client_read(vs);
- }
- if (condition & G_IO_OUT) {
- vnc_client_write(vs);
- }
- return TRUE;
-}
-
-
-void vnc_write(VncState *vs, const void *data, size_t len)
-{
- buffer_reserve(&vs->output, len);
-
- if (vs->ioc != NULL && buffer_empty(&vs->output)) {
- if (vs->ioc_tag) {
- g_source_remove(vs->ioc_tag);
- }
- vs->ioc_tag = qio_channel_add_watch(
- vs->ioc, G_IO_IN | G_IO_OUT, vnc_client_io, vs, NULL);
- }
-
- buffer_append(&vs->output, data, len);
-}
-
-void vnc_write_s32(VncState *vs, int32_t value)
-{
- vnc_write_u32(vs, *(uint32_t *)&value);
-}
-
-void vnc_write_u32(VncState *vs, uint32_t value)
-{
- uint8_t buf[4];
-
- buf[0] = (value >> 24) & 0xFF;
- buf[1] = (value >> 16) & 0xFF;
- buf[2] = (value >> 8) & 0xFF;
- buf[3] = value & 0xFF;
-
- vnc_write(vs, buf, 4);
-}
-
-void vnc_write_u16(VncState *vs, uint16_t value)
-{
- uint8_t buf[2];
-
- buf[0] = (value >> 8) & 0xFF;
- buf[1] = value & 0xFF;
-
- vnc_write(vs, buf, 2);
-}
-
-void vnc_write_u8(VncState *vs, uint8_t value)
-{
- vnc_write(vs, (char *)&value, 1);
-}
-
-void vnc_flush(VncState *vs)
-{
- vnc_lock_output(vs);
- if (vs->ioc != NULL && vs->output.offset) {
- vnc_client_write_locked(vs);
- }
- vnc_unlock_output(vs);
-}
-
-static uint8_t read_u8(uint8_t *data, size_t offset)
-{
- return data[offset];
-}
-
-static uint16_t read_u16(uint8_t *data, size_t offset)
-{
- return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
-}
-
-static int32_t read_s32(uint8_t *data, size_t offset)
-{
- return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
- (data[offset + 2] << 8) | data[offset + 3]);
-}
-
-uint32_t read_u32(uint8_t *data, size_t offset)
-{
- return ((data[offset] << 24) | (data[offset + 1] << 16) |
- (data[offset + 2] << 8) | data[offset + 3]);
-}
-
-static void client_cut_text(VncState *vs, size_t len, uint8_t *text)
-{
-}
-
-static void check_pointer_type_change(Notifier *notifier, void *data)
-{
- VncState *vs = container_of(notifier, VncState, mouse_mode_notifier);
- int absolute = qemu_input_is_absolute();
-
- if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) && vs->absolute != absolute) {
- vnc_lock_output(vs);
- vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
- vnc_write_u8(vs, 0);
- vnc_write_u16(vs, 1);
- vnc_framebuffer_update(vs, absolute, 0,
- pixman_image_get_width(vs->vd->server),
- pixman_image_get_height(vs->vd->server),
- VNC_ENCODING_POINTER_TYPE_CHANGE);
- vnc_unlock_output(vs);
- vnc_flush(vs);
- }
- vs->absolute = absolute;
-}
-
-static void pointer_event(VncState *vs, int button_mask, int x, int y)
-{
- static uint32_t bmap[INPUT_BUTTON__MAX] = {
- [INPUT_BUTTON_LEFT] = 0x01,
- [INPUT_BUTTON_MIDDLE] = 0x02,
- [INPUT_BUTTON_RIGHT] = 0x04,
- [INPUT_BUTTON_WHEEL_UP] = 0x08,
- [INPUT_BUTTON_WHEEL_DOWN] = 0x10,
- };
- QemuConsole *con = vs->vd->dcl.con;
- int width = pixman_image_get_width(vs->vd->server);
- int height = pixman_image_get_height(vs->vd->server);
-
- if (vs->last_bmask != button_mask) {
- qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask);
- vs->last_bmask = button_mask;
- }
-
- if (vs->absolute) {
- qemu_input_queue_abs(con, INPUT_AXIS_X, x, width);
- qemu_input_queue_abs(con, INPUT_AXIS_Y, y, height);
- } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
- qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF);
- qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF);
- } else {
- if (vs->last_x != -1) {
- qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs->last_x);
- qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs->last_y);
- }
- vs->last_x = x;
- vs->last_y = y;
- }
- qemu_input_event_sync();
-}
-
-static void reset_keys(VncState *vs)
-{
- int i;
- for(i = 0; i < 256; i++) {
- if (vs->modifiers_state[i]) {
- qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
- vs->modifiers_state[i] = 0;
- }
- }
-}
-
-static void press_key(VncState *vs, int keysym)
-{
- int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
- qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
- qemu_input_event_send_key_delay(0);
- qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
- qemu_input_event_send_key_delay(0);
-}
-
-static int current_led_state(VncState *vs)
-{
- int ledstate = 0;
-
- if (vs->modifiers_state[0x46]) {
- ledstate |= QEMU_SCROLL_LOCK_LED;
- }
- if (vs->modifiers_state[0x45]) {
- ledstate |= QEMU_NUM_LOCK_LED;
- }
- if (vs->modifiers_state[0x3a]) {
- ledstate |= QEMU_CAPS_LOCK_LED;
- }
-
- return ledstate;
-}
-
-static void vnc_led_state_change(VncState *vs)
-{
- int ledstate = 0;
-
- if (!vnc_has_feature(vs, VNC_FEATURE_LED_STATE)) {
- return;
- }
-
- ledstate = current_led_state(vs);
- vnc_lock_output(vs);
- vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
- vnc_write_u8(vs, 0);
- vnc_write_u16(vs, 1);
- vnc_framebuffer_update(vs, 0, 0, 1, 1, VNC_ENCODING_LED_STATE);
- vnc_write_u8(vs, ledstate);
- vnc_unlock_output(vs);
- vnc_flush(vs);
-}
-
-static void kbd_leds(void *opaque, int ledstate)
-{
- VncState *vs = opaque;
- int caps, num, scr;
- bool has_changed = (ledstate != current_led_state(vs));
-
- trace_vnc_key_guest_leds((ledstate & QEMU_CAPS_LOCK_LED),
- (ledstate & QEMU_NUM_LOCK_LED),
- (ledstate & QEMU_SCROLL_LOCK_LED));
-
- caps = ledstate & QEMU_CAPS_LOCK_LED ? 1 : 0;
- num = ledstate & QEMU_NUM_LOCK_LED ? 1 : 0;
- scr = ledstate & QEMU_SCROLL_LOCK_LED ? 1 : 0;
-
- if (vs->modifiers_state[0x3a] != caps) {
- vs->modifiers_state[0x3a] = caps;
- }
- if (vs->modifiers_state[0x45] != num) {
- vs->modifiers_state[0x45] = num;
- }
- if (vs->modifiers_state[0x46] != scr) {
- vs->modifiers_state[0x46] = scr;
- }
-
- /* Sending the current led state message to the client */
- if (has_changed) {
- vnc_led_state_change(vs);
- }
-}
-
-static void do_key_event(VncState *vs, int down, int keycode, int sym)
-{
- /* QEMU console switch */
- switch(keycode) {
- case 0x2a: /* Left Shift */
- case 0x36: /* Right Shift */
- case 0x1d: /* Left CTRL */
- case 0x9d: /* Right CTRL */
- case 0x38: /* Left ALT */
- case 0xb8: /* Right ALT */
- if (down)
- vs->modifiers_state[keycode] = 1;
- else
- vs->modifiers_state[keycode] = 0;
- break;
- case 0x02 ... 0x0a: /* '1' to '9' keys */
- if (vs->vd->dcl.con == NULL &&
- down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
- /* Reset the modifiers sent to the current console */
- reset_keys(vs);
- console_select(keycode - 0x02);
- return;
- }
- break;
- case 0x3a: /* CapsLock */
- case 0x45: /* NumLock */
- if (down)
- vs->modifiers_state[keycode] ^= 1;
- break;
- }
-
- /* Turn off the lock state sync logic if the client support the led
- state extension.
- */
- if (down && vs->vd->lock_key_sync &&
- !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
- keycode_is_keypad(vs->vd->kbd_layout, keycode)) {
- /* If the numlock state needs to change then simulate an additional
- keypress before sending this one. This will happen if the user
- toggles numlock away from the VNC window.
- */
- if (keysym_is_numlock(vs->vd->kbd_layout, sym & 0xFFFF)) {
- if (!vs->modifiers_state[0x45]) {
- trace_vnc_key_sync_numlock(true);
- vs->modifiers_state[0x45] = 1;
- press_key(vs, 0xff7f);
- }
- } else {
- if (vs->modifiers_state[0x45]) {
- trace_vnc_key_sync_numlock(false);
- vs->modifiers_state[0x45] = 0;
- press_key(vs, 0xff7f);
- }
- }
- }
-
- if (down && vs->vd->lock_key_sync &&
- !vnc_has_feature(vs, VNC_FEATURE_LED_STATE) &&
- ((sym >= 'A' && sym <= 'Z') || (sym >= 'a' && sym <= 'z'))) {
- /* If the capslock state needs to change then simulate an additional
- keypress before sending this one. This will happen if the user
- toggles capslock away from the VNC window.
- */
- int uppercase = !!(sym >= 'A' && sym <= 'Z');
- int shift = !!(vs->modifiers_state[0x2a] | vs->modifiers_state[0x36]);
- int capslock = !!(vs->modifiers_state[0x3a]);
- if (capslock) {
- if (uppercase == shift) {
- trace_vnc_key_sync_capslock(false);
- vs->modifiers_state[0x3a] = 0;
- press_key(vs, 0xffe5);
- }
- } else {
- if (uppercase != shift) {
- trace_vnc_key_sync_capslock(true);
- vs->modifiers_state[0x3a] = 1;
- press_key(vs, 0xffe5);
- }
- }
- }
-
- if (qemu_console_is_graphic(NULL)) {
- qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
- } else {
- bool numlock = vs->modifiers_state[0x45];
- bool control = (vs->modifiers_state[0x1d] ||
- vs->modifiers_state[0x9d]);
- /* QEMU console emulation */
- if (down) {
- switch (keycode) {
- case 0x2a: /* Left Shift */
- case 0x36: /* Right Shift */
- case 0x1d: /* Left CTRL */
- case 0x9d: /* Right CTRL */
- case 0x38: /* Left ALT */
- case 0xb8: /* Right ALT */
- break;
- case 0xc8:
- kbd_put_keysym(QEMU_KEY_UP);
- break;
- case 0xd0:
- kbd_put_keysym(QEMU_KEY_DOWN);
- break;
- case 0xcb:
- kbd_put_keysym(QEMU_KEY_LEFT);
- break;
- case 0xcd:
- kbd_put_keysym(QEMU_KEY_RIGHT);
- break;
- case 0xd3:
- kbd_put_keysym(QEMU_KEY_DELETE);
- break;
- case 0xc7:
- kbd_put_keysym(QEMU_KEY_HOME);
- break;
- case 0xcf:
- kbd_put_keysym(QEMU_KEY_END);
- break;
- case 0xc9:
- kbd_put_keysym(QEMU_KEY_PAGEUP);
- break;
- case 0xd1:
- kbd_put_keysym(QEMU_KEY_PAGEDOWN);
- break;
-
- case 0x47:
- kbd_put_keysym(numlock ? '7' : QEMU_KEY_HOME);
- break;
- case 0x48:
- kbd_put_keysym(numlock ? '8' : QEMU_KEY_UP);
- break;
- case 0x49:
- kbd_put_keysym(numlock ? '9' : QEMU_KEY_PAGEUP);
- break;
- case 0x4b:
- kbd_put_keysym(numlock ? '4' : QEMU_KEY_LEFT);
- break;
- case 0x4c:
- kbd_put_keysym('5');
- break;
- case 0x4d:
- kbd_put_keysym(numlock ? '6' : QEMU_KEY_RIGHT);
- break;
- case 0x4f:
- kbd_put_keysym(numlock ? '1' : QEMU_KEY_END);
- break;
- case 0x50:
- kbd_put_keysym(numlock ? '2' : QEMU_KEY_DOWN);
- break;
- case 0x51:
- kbd_put_keysym(numlock ? '3' : QEMU_KEY_PAGEDOWN);
- break;
- case 0x52:
- kbd_put_keysym('0');
- break;
- case 0x53:
- kbd_put_keysym(numlock ? '.' : QEMU_KEY_DELETE);
- break;
-
- case 0xb5:
- kbd_put_keysym('/');
- break;
- case 0x37:
- kbd_put_keysym('*');
- break;
- case 0x4a:
- kbd_put_keysym('-');
- break;
- case 0x4e:
- kbd_put_keysym('+');
- break;
- case 0x9c:
- kbd_put_keysym('\n');
- break;
-
- default:
- if (control) {
- kbd_put_keysym(sym & 0x1f);
- } else {
- kbd_put_keysym(sym);
- }
- break;
- }
- }
- }
-}
-
-static void vnc_release_modifiers(VncState *vs)
-{
- static const int keycodes[] = {
- /* shift, control, alt keys, both left & right */
- 0x2a, 0x36, 0x1d, 0x9d, 0x38, 0xb8,
- };
- int i, keycode;
-
- if (!qemu_console_is_graphic(NULL)) {
- return;
- }
- for (i = 0; i < ARRAY_SIZE(keycodes); i++) {
- keycode = keycodes[i];
- if (!vs->modifiers_state[keycode]) {
- continue;
- }
- qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
- }
-}
-
-static const char *code2name(int keycode)
-{
- return QKeyCode_lookup[qemu_input_key_number_to_qcode(keycode)];
-}
-
-static void key_event(VncState *vs, int down, uint32_t sym)
-{
- int keycode;
- int lsym = sym;
-
- if (lsym >= 'A' && lsym <= 'Z' && qemu_console_is_graphic(NULL)) {
- lsym = lsym - 'A' + 'a';
- }
-
- keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF) & SCANCODE_KEYMASK;
- trace_vnc_key_event_map(down, sym, keycode, code2name(keycode));
- do_key_event(vs, down, keycode, sym);
-}
-
-static void ext_key_event(VncState *vs, int down,
- uint32_t sym, uint16_t keycode)
-{
- /* if the user specifies a keyboard layout, always use it */
- if (keyboard_layout) {
- key_event(vs, down, sym);
- } else {
- trace_vnc_key_event_ext(down, sym, keycode, code2name(keycode));
- do_key_event(vs, down, keycode, sym);
- }
-}
-
-static void framebuffer_update_request(VncState *vs, int incremental,
- int x, int y, int w, int h)
-{
- vs->need_update = 1;
-
- if (incremental) {
- return;
- }
-
- vs->force_update = 1;
- vnc_set_area_dirty(vs->dirty, vs->vd, x, y, w, h);
-}
-
-static void send_ext_key_event_ack(VncState *vs)
-{
- vnc_lock_output(vs);
- vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
- vnc_write_u8(vs, 0);
- vnc_write_u16(vs, 1);
- vnc_framebuffer_update(vs, 0, 0,
- pixman_image_get_width(vs->vd->server),
- pixman_image_get_height(vs->vd->server),
- VNC_ENCODING_EXT_KEY_EVENT);
- vnc_unlock_output(vs);
- vnc_flush(vs);
-}
-
-static void send_ext_audio_ack(VncState *vs)
-{
- vnc_lock_output(vs);
- vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
- vnc_write_u8(vs, 0);
- vnc_write_u16(vs, 1);
- vnc_framebuffer_update(vs, 0, 0,
- pixman_image_get_width(vs->vd->server),
- pixman_image_get_height(vs->vd->server),
- VNC_ENCODING_AUDIO);
- vnc_unlock_output(vs);
- vnc_flush(vs);
-}
-
-static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
-{
- int i;
- unsigned int enc = 0;
-
- vs->features = 0;
- vs->vnc_encoding = 0;
- vs->tight.compression = 9;
- vs->tight.quality = -1; /* Lossless by default */
- vs->absolute = -1;
-
- /*
- * Start from the end because the encodings are sent in order of preference.
- * This way the preferred encoding (first encoding defined in the array)
- * will be set at the end of the loop.
- */
- for (i = n_encodings - 1; i >= 0; i--) {
- enc = encodings[i];
- switch (enc) {
- case VNC_ENCODING_RAW:
- vs->vnc_encoding = enc;
- break;
- case VNC_ENCODING_COPYRECT:
- vs->features |= VNC_FEATURE_COPYRECT_MASK;
- break;
- case VNC_ENCODING_HEXTILE:
- vs->features |= VNC_FEATURE_HEXTILE_MASK;
- vs->vnc_encoding = enc;
- break;
- case VNC_ENCODING_TIGHT:
- vs->features |= VNC_FEATURE_TIGHT_MASK;
- vs->vnc_encoding = enc;
- break;
-#ifdef CONFIG_VNC_PNG
- case VNC_ENCODING_TIGHT_PNG:
- vs->features |= VNC_FEATURE_TIGHT_PNG_MASK;
- vs->vnc_encoding = enc;
- break;
-#endif
- case VNC_ENCODING_ZLIB:
- vs->features |= VNC_FEATURE_ZLIB_MASK;
- vs->vnc_encoding = enc;
- break;
- case VNC_ENCODING_ZRLE:
- vs->features |= VNC_FEATURE_ZRLE_MASK;
- vs->vnc_encoding = enc;
- break;
- case VNC_ENCODING_ZYWRLE:
- vs->features |= VNC_FEATURE_ZYWRLE_MASK;
- vs->vnc_encoding = enc;
- break;
- case VNC_ENCODING_DESKTOPRESIZE:
- vs->features |= VNC_FEATURE_RESIZE_MASK;
- break;
- case VNC_ENCODING_POINTER_TYPE_CHANGE:
- vs->features |= VNC_FEATURE_POINTER_TYPE_CHANGE_MASK;
- break;
- case VNC_ENCODING_RICH_CURSOR:
- vs->features |= VNC_FEATURE_RICH_CURSOR_MASK;
- if (vs->vd->cursor) {
- vnc_cursor_define(vs);
- }
- break;
- case VNC_ENCODING_EXT_KEY_EVENT:
- send_ext_key_event_ack(vs);
- break;
- case VNC_ENCODING_AUDIO:
- send_ext_audio_ack(vs);
- break;
- case VNC_ENCODING_WMVi:
- vs->features |= VNC_FEATURE_WMVI_MASK;
- break;
- case VNC_ENCODING_LED_STATE:
- vs->features |= VNC_FEATURE_LED_STATE_MASK;
- break;
- case VNC_ENCODING_COMPRESSLEVEL0 ... VNC_ENCODING_COMPRESSLEVEL0 + 9:
- vs->tight.compression = (enc & 0x0F);
- break;
- case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9:
- if (vs->vd->lossy) {
- vs->tight.quality = (enc & 0x0F);
- }
- break;
- default:
- VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc);
- break;
- }
- }
- vnc_desktop_resize(vs);
- check_pointer_type_change(&vs->mouse_mode_notifier, NULL);
- vnc_led_state_change(vs);
-}
-
-static void set_pixel_conversion(VncState *vs)
-{
- pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
-
- if (fmt == VNC_SERVER_FB_FORMAT) {
- vs->write_pixels = vnc_write_pixels_copy;
- vnc_hextile_set_pixel_conversion(vs, 0);
- } else {
- vs->write_pixels = vnc_write_pixels_generic;
- vnc_hextile_set_pixel_conversion(vs, 1);
- }
-}
-
-static void set_pixel_format(VncState *vs,
- int bits_per_pixel, int depth,
- int big_endian_flag, int true_color_flag,
- int red_max, int green_max, int blue_max,
- int red_shift, int green_shift, int blue_shift)
-{
- if (!true_color_flag) {
- vnc_client_error(vs);
- return;
- }
-
- switch (bits_per_pixel) {
- case 8:
- case 16:
- case 32:
- break;
- default:
- vnc_client_error(vs);
- return;
- }
-
- vs->client_pf.rmax = red_max ? red_max : 0xFF;
- vs->client_pf.rbits = hweight_long(red_max);
- vs->client_pf.rshift = red_shift;
- vs->client_pf.rmask = red_max << red_shift;
- vs->client_pf.gmax = green_max ? green_max : 0xFF;
- vs->client_pf.gbits = hweight_long(green_max);
- vs->client_pf.gshift = green_shift;
- vs->client_pf.gmask = green_max << green_shift;
- vs->client_pf.bmax = blue_max ? blue_max : 0xFF;
- vs->client_pf.bbits = hweight_long(blue_max);
- vs->client_pf.bshift = blue_shift;
- vs->client_pf.bmask = blue_max << blue_shift;
- vs->client_pf.bits_per_pixel = bits_per_pixel;
- vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
- vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
- vs->client_be = big_endian_flag;
-
- set_pixel_conversion(vs);
-
- graphic_hw_invalidate(vs->vd->dcl.con);
- graphic_hw_update(vs->vd->dcl.con);
-}
-
-static void pixel_format_message (VncState *vs) {
- char pad[3] = { 0, 0, 0 };
-
- vs->client_pf = qemu_default_pixelformat(32);
-
- vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
- vnc_write_u8(vs, vs->client_pf.depth); /* depth */
-
-#ifdef HOST_WORDS_BIGENDIAN
- vnc_write_u8(vs, 1); /* big-endian-flag */
-#else
- vnc_write_u8(vs, 0); /* big-endian-flag */
-#endif
- vnc_write_u8(vs, 1); /* true-color-flag */
- vnc_write_u16(vs, vs->client_pf.rmax); /* red-max */
- vnc_write_u16(vs, vs->client_pf.gmax); /* green-max */
- vnc_write_u16(vs, vs->client_pf.bmax); /* blue-max */
- vnc_write_u8(vs, vs->client_pf.rshift); /* red-shift */
- vnc_write_u8(vs, vs->client_pf.gshift); /* green-shift */
- vnc_write_u8(vs, vs->client_pf.bshift); /* blue-shift */
- vnc_write(vs, pad, 3); /* padding */
-
- vnc_hextile_set_pixel_conversion(vs, 0);
- vs->write_pixels = vnc_write_pixels_copy;
-}
-
-static void vnc_colordepth(VncState *vs)
-{
- if (vnc_has_feature(vs, VNC_FEATURE_WMVI)) {
- /* Sending a WMVi message to notify the client*/
- vnc_lock_output(vs);
- vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
- vnc_write_u8(vs, 0);
- vnc_write_u16(vs, 1); /* number of rects */
- vnc_framebuffer_update(vs, 0, 0,
- pixman_image_get_width(vs->vd->server),
- pixman_image_get_height(vs->vd->server),
- VNC_ENCODING_WMVi);
- pixel_format_message(vs);
- vnc_unlock_output(vs);
- vnc_flush(vs);
- } else {
- set_pixel_conversion(vs);
- }
-}
-
-static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
-{
- int i;
- uint16_t limit;
- VncDisplay *vd = vs->vd;
-
- if (data[0] > 3) {
- update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
- }
-
- switch (data[0]) {
- case VNC_MSG_CLIENT_SET_PIXEL_FORMAT:
- if (len == 1)
- return 20;
-
- set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),
- read_u8(data, 6), read_u8(data, 7),
- read_u16(data, 8), read_u16(data, 10),
- read_u16(data, 12), read_u8(data, 14),
- read_u8(data, 15), read_u8(data, 16));
- break;
- case VNC_MSG_CLIENT_SET_ENCODINGS:
- if (len == 1)
- return 4;
-
- if (len == 4) {
- limit = read_u16(data, 2);
- if (limit > 0)
- return 4 + (limit * 4);
- } else
- limit = read_u16(data, 2);
-
- for (i = 0; i < limit; i++) {
- int32_t val = read_s32(data, 4 + (i * 4));
- memcpy(data + 4 + (i * 4), &val, sizeof(val));
- }
-
- set_encodings(vs, (int32_t *)(data + 4), limit);
- break;
- case VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST:
- if (len == 1)
- return 10;
-
- framebuffer_update_request(vs,
- read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),
- read_u16(data, 6), read_u16(data, 8));
- break;
- case VNC_MSG_CLIENT_KEY_EVENT:
- if (len == 1)
- return 8;
-
- key_event(vs, read_u8(data, 1), read_u32(data, 4));
- break;
- case VNC_MSG_CLIENT_POINTER_EVENT:
- if (len == 1)
- return 6;
-
- pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));
- break;
- case VNC_MSG_CLIENT_CUT_TEXT:
- if (len == 1) {
- return 8;
- }
- if (len == 8) {
- uint32_t dlen = read_u32(data, 4);
- if (dlen > (1 << 20)) {
- error_report("vnc: client_cut_text msg payload has %u bytes"
- " which exceeds our limit of 1MB.", dlen);
- vnc_client_error(vs);
- break;
- }
- if (dlen > 0) {
- return 8 + dlen;
- }
- }
-
- client_cut_text(vs, read_u32(data, 4), data + 8);
- break;
- case VNC_MSG_CLIENT_QEMU:
- if (len == 1)
- return 2;
-
- switch (read_u8(data, 1)) {
- case VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT:
- if (len == 2)
- return 12;
-
- ext_key_event(vs, read_u16(data, 2),
- read_u32(data, 4), read_u32(data, 8));
- break;
- case VNC_MSG_CLIENT_QEMU_AUDIO:
- if (len == 2)
- return 4;
-
- switch (read_u16 (data, 2)) {
- case VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE:
- audio_add(vs);
- break;
- case VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE:
- audio_del(vs);
- break;
- case VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT:
- if (len == 4)
- return 10;
- switch (read_u8(data, 4)) {
- case 0: vs->as.fmt = AUD_FMT_U8; break;
- case 1: vs->as.fmt = AUD_FMT_S8; break;
- case 2: vs->as.fmt = AUD_FMT_U16; break;
- case 3: vs->as.fmt = AUD_FMT_S16; break;
- case 4: vs->as.fmt = AUD_FMT_U32; break;
- case 5: vs->as.fmt = AUD_FMT_S32; break;
- default:
- VNC_DEBUG("Invalid audio format %d\n", read_u8(data, 4));
- vnc_client_error(vs);
- break;
- }
- vs->as.nchannels = read_u8(data, 5);
- if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {
- VNC_DEBUG("Invalid audio channel coount %d\n",
- read_u8(data, 5));
- vnc_client_error(vs);
- break;
- }
- vs->as.freq = read_u32(data, 6);
- break;
- default:
- VNC_DEBUG("Invalid audio message %d\n", read_u8(data, 4));
- vnc_client_error(vs);
- break;
- }
- break;
-
- default:
- VNC_DEBUG("Msg: %d\n", read_u16(data, 0));
- vnc_client_error(vs);
- break;
- }
- break;
- default:
- VNC_DEBUG("Msg: %d\n", data[0]);
- vnc_client_error(vs);
- break;
- }
-
- vnc_read_when(vs, protocol_client_msg, 1);
- return 0;
-}
-
-static int protocol_client_init(VncState *vs, uint8_t *data, size_t len)
-{
- char buf[1024];
- VncShareMode mode;
- int size;
-
- mode = data[0] ? VNC_SHARE_MODE_SHARED : VNC_SHARE_MODE_EXCLUSIVE;
- switch (vs->vd->share_policy) {
- case VNC_SHARE_POLICY_IGNORE:
- /*
- * Ignore the shared flag. Nothing to do here.
- *
- * Doesn't conform to the rfb spec but is traditional qemu
- * behavior, thus left here as option for compatibility
- * reasons.
- */
- break;
- case VNC_SHARE_POLICY_ALLOW_EXCLUSIVE:
- /*
- * Policy: Allow clients ask for exclusive access.
- *
- * Implementation: When a client asks for exclusive access,
- * disconnect all others. Shared connects are allowed as long
- * as no exclusive connection exists.
- *
- * This is how the rfb spec suggests to handle the shared flag.
- */
- if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
- VncState *client;
- QTAILQ_FOREACH(client, &vs->vd->clients, next) {
- if (vs == client) {
- continue;
- }
- if (client->share_mode != VNC_SHARE_MODE_EXCLUSIVE &&
- client->share_mode != VNC_SHARE_MODE_SHARED) {
- continue;
- }
- vnc_disconnect_start(client);
- }
- }
- if (mode == VNC_SHARE_MODE_SHARED) {
- if (vs->vd->num_exclusive > 0) {
- vnc_disconnect_start(vs);
- return 0;
- }
- }
- break;
- case VNC_SHARE_POLICY_FORCE_SHARED:
- /*
- * Policy: Shared connects only.
- * Implementation: Disallow clients asking for exclusive access.
- *
- * Useful for shared desktop sessions where you don't want
- * someone forgetting to say -shared when running the vnc
- * client disconnect everybody else.
- */
- if (mode == VNC_SHARE_MODE_EXCLUSIVE) {
- vnc_disconnect_start(vs);
- return 0;
- }
- break;
- }
- vnc_set_share_mode(vs, mode);
-
- if (vs->vd->num_shared > vs->vd->connections_limit) {
- vnc_disconnect_start(vs);
- return 0;
- }
-
- vs->client_width = pixman_image_get_width(vs->vd->server);
- vs->client_height = pixman_image_get_height(vs->vd->server);
- vnc_write_u16(vs, vs->client_width);
- vnc_write_u16(vs, vs->client_height);
-
- pixel_format_message(vs);
-
- if (qemu_name)
- size = snprintf(buf, sizeof(buf), "QEMU (%s)", qemu_name);
- else
- size = snprintf(buf, sizeof(buf), "QEMU");
-
- vnc_write_u32(vs, size);
- vnc_write(vs, buf, size);
- vnc_flush(vs);
-
- vnc_client_cache_auth(vs);
- vnc_qmp_event(vs, QAPI_EVENT_VNC_INITIALIZED);
-
- vnc_read_when(vs, protocol_client_msg, 1);
-
- return 0;
-}
-
-void start_client_init(VncState *vs)
-{
- vnc_read_when(vs, protocol_client_init, 1);
-}
-
-static void make_challenge(VncState *vs)
-{
- int i;
-
- srand(time(NULL)+getpid()+getpid()*987654+rand());
-
- for (i = 0 ; i < sizeof(vs->challenge) ; i++)
- vs->challenge[i] = (int) (256.0*rand()/(RAND_MAX+1.0));
-}
-
-static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
-{
- unsigned char response[VNC_AUTH_CHALLENGE_SIZE];
- size_t i, pwlen;
- unsigned char key[8];
- time_t now = time(NULL);
- QCryptoCipher *cipher = NULL;
- Error *err = NULL;
-
- if (!vs->vd->password) {
- VNC_DEBUG("No password configured on server");
- goto reject;
- }
- if (vs->vd->expires < now) {
- VNC_DEBUG("Password is expired");
- goto reject;
- }
-
- memcpy(response, vs->challenge, VNC_AUTH_CHALLENGE_SIZE);
-
- /* Calculate the expected challenge response */
- pwlen = strlen(vs->vd->password);
- for (i=0; i<sizeof(key); i++)
- key[i] = i<pwlen ? vs->vd->password[i] : 0;
-
- cipher = qcrypto_cipher_new(
- QCRYPTO_CIPHER_ALG_DES_RFB,
- QCRYPTO_CIPHER_MODE_ECB,
- key, G_N_ELEMENTS(key),
- &err);
- if (!cipher) {
- VNC_DEBUG("Cannot initialize cipher %s",
- error_get_pretty(err));
- error_free(err);
- goto reject;
- }
-
- if (qcrypto_cipher_encrypt(cipher,
- vs->challenge,
- response,
- VNC_AUTH_CHALLENGE_SIZE,
- &err) < 0) {
- VNC_DEBUG("Cannot encrypt challenge %s",
- error_get_pretty(err));
- error_free(err);
- goto reject;
- }
-
- /* Compare expected vs actual challenge response */
- if (memcmp(response, data, VNC_AUTH_CHALLENGE_SIZE) != 0) {
- VNC_DEBUG("Client challenge response did not match\n");
- goto reject;
- } else {
- VNC_DEBUG("Accepting VNC challenge response\n");
- vnc_write_u32(vs, 0); /* Accept auth */
- vnc_flush(vs);
-
- start_client_init(vs);
- }
-
- qcrypto_cipher_free(cipher);
- return 0;
-
-reject:
- vnc_write_u32(vs, 1); /* Reject auth */
- if (vs->minor >= 8) {
- static const char err[] = "Authentication failed";
- vnc_write_u32(vs, sizeof(err));
- vnc_write(vs, err, sizeof(err));
- }
- vnc_flush(vs);
- vnc_client_error(vs);
- qcrypto_cipher_free(cipher);
- return 0;
-}
-
-void start_auth_vnc(VncState *vs)
-{
- make_challenge(vs);
- /* Send client a 'random' challenge */
- vnc_write(vs, vs->challenge, sizeof(vs->challenge));
- vnc_flush(vs);
-
- vnc_read_when(vs, protocol_client_auth_vnc, sizeof(vs->challenge));
-}
-
-
-static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len)
-{
- /* We only advertise 1 auth scheme at a time, so client
- * must pick the one we sent. Verify this */
- if (data[0] != vs->auth) { /* Reject auth */
- VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
- vnc_write_u32(vs, 1);
- if (vs->minor >= 8) {
- static const char err[] = "Authentication failed";
- vnc_write_u32(vs, sizeof(err));
- vnc_write(vs, err, sizeof(err));
- }
- vnc_client_error(vs);
- } else { /* Accept requested auth */
- VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
- switch (vs->auth) {
- case VNC_AUTH_NONE:
- VNC_DEBUG("Accept auth none\n");
- if (vs->minor >= 8) {
- vnc_write_u32(vs, 0); /* Accept auth completion */
- vnc_flush(vs);
- }
- start_client_init(vs);
- break;
-
- case VNC_AUTH_VNC:
- VNC_DEBUG("Start VNC auth\n");
- start_auth_vnc(vs);
- break;
-
- case VNC_AUTH_VENCRYPT:
- VNC_DEBUG("Accept VeNCrypt auth\n");
- start_auth_vencrypt(vs);
- break;
-
-#ifdef CONFIG_VNC_SASL
- case VNC_AUTH_SASL:
- VNC_DEBUG("Accept SASL auth\n");
- start_auth_sasl(vs);
- break;
-#endif /* CONFIG_VNC_SASL */
-
- default: /* Should not be possible, but just in case */
- VNC_DEBUG("Reject auth %d server code bug\n", vs->auth);
- vnc_write_u8(vs, 1);
- if (vs->minor >= 8) {
- static const char err[] = "Authentication failed";
- vnc_write_u32(vs, sizeof(err));
- vnc_write(vs, err, sizeof(err));
- }
- vnc_client_error(vs);
- }
- }
- return 0;
-}
-
-static int protocol_version(VncState *vs, uint8_t *version, size_t len)
-{
- char local[13];
-
- memcpy(local, version, 12);
- local[12] = 0;
-
- if (sscanf(local, "RFB %03d.%03d\n", &vs->major, &vs->minor) != 2) {
- VNC_DEBUG("Malformed protocol version %s\n", local);
- vnc_client_error(vs);
- return 0;
- }
- VNC_DEBUG("Client request protocol version %d.%d\n", vs->major, vs->minor);
- if (vs->major != 3 ||
- (vs->minor != 3 &&
- vs->minor != 4 &&
- vs->minor != 5 &&
- vs->minor != 7 &&
- vs->minor != 8)) {
- VNC_DEBUG("Unsupported client version\n");
- vnc_write_u32(vs, VNC_AUTH_INVALID);
- vnc_flush(vs);
- vnc_client_error(vs);
- return 0;
- }
- /* Some broken clients report v3.4 or v3.5, which spec requires to be treated
- * as equivalent to v3.3 by servers
- */
- if (vs->minor == 4 || vs->minor == 5)
- vs->minor = 3;
-
- if (vs->minor == 3) {
- if (vs->auth == VNC_AUTH_NONE) {
- VNC_DEBUG("Tell client auth none\n");
- vnc_write_u32(vs, vs->auth);
- vnc_flush(vs);
- start_client_init(vs);
- } else if (vs->auth == VNC_AUTH_VNC) {
- VNC_DEBUG("Tell client VNC auth\n");
- vnc_write_u32(vs, vs->auth);
- vnc_flush(vs);
- start_auth_vnc(vs);
- } else {
- VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth);
- vnc_write_u32(vs, VNC_AUTH_INVALID);
- vnc_flush(vs);
- vnc_client_error(vs);
- }
- } else {
- VNC_DEBUG("Telling client we support auth %d\n", vs->auth);
- vnc_write_u8(vs, 1); /* num auth */
- vnc_write_u8(vs, vs->auth);
- vnc_read_when(vs, protocol_client_auth, 1);
- vnc_flush(vs);
- }
-
- return 0;
-}
-
-static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y)
-{
- struct VncSurface *vs = &vd->guest;
-
- return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT];
-}
-
-void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h)
-{
- int i, j;
-
- w = (x + w) / VNC_STAT_RECT;
- h = (y + h) / VNC_STAT_RECT;
- x /= VNC_STAT_RECT;
- y /= VNC_STAT_RECT;
-
- for (j = y; j <= h; j++) {
- for (i = x; i <= w; i++) {
- vs->lossy_rect[j][i] = 1;
- }
- }
-}
-
-static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
-{
- VncState *vs;
- int sty = y / VNC_STAT_RECT;
- int stx = x / VNC_STAT_RECT;
- int has_dirty = 0;
-
- y = y / VNC_STAT_RECT * VNC_STAT_RECT;
- x = x / VNC_STAT_RECT * VNC_STAT_RECT;
-
- QTAILQ_FOREACH(vs, &vd->clients, next) {
- int j;
-
- /* kernel send buffers are full -> refresh later */
- if (vs->output.offset) {
- continue;
- }
-
- if (!vs->lossy_rect[sty][stx]) {
- continue;
- }
-
- vs->lossy_rect[sty][stx] = 0;
- for (j = 0; j < VNC_STAT_RECT; ++j) {
- bitmap_set(vs->dirty[y + j],
- x / VNC_DIRTY_PIXELS_PER_BIT,
- VNC_STAT_RECT / VNC_DIRTY_PIXELS_PER_BIT);
- }
- has_dirty++;
- }
-
- return has_dirty;
-}
-
-static int vnc_update_stats(VncDisplay *vd, struct timeval * tv)
-{
- int width = pixman_image_get_width(vd->guest.fb);
- int height = pixman_image_get_height(vd->guest.fb);
- int x, y;
- struct timeval res;
- int has_dirty = 0;
-
- for (y = 0; y < height; y += VNC_STAT_RECT) {
- for (x = 0; x < width; x += VNC_STAT_RECT) {
- VncRectStat *rect = vnc_stat_rect(vd, x, y);
-
- rect->updated = false;
- }
- }
-
- qemu_timersub(tv, &VNC_REFRESH_STATS, &res);
-
- if (timercmp(&vd->guest.last_freq_check, &res, >)) {
- return has_dirty;
- }
- vd->guest.last_freq_check = *tv;
-
- for (y = 0; y < height; y += VNC_STAT_RECT) {
- for (x = 0; x < width; x += VNC_STAT_RECT) {
- VncRectStat *rect= vnc_stat_rect(vd, x, y);
- int count = ARRAY_SIZE(rect->times);
- struct timeval min, max;
-
- if (!timerisset(&rect->times[count - 1])) {
- continue ;
- }
-
- max = rect->times[(rect->idx + count - 1) % count];
- qemu_timersub(tv, &max, &res);
-
- if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) {
- rect->freq = 0;
- has_dirty += vnc_refresh_lossy_rect(vd, x, y);
- memset(rect->times, 0, sizeof (rect->times));
- continue ;
- }
-
- min = rect->times[rect->idx];
- max = rect->times[(rect->idx + count - 1) % count];
- qemu_timersub(&max, &min, &res);
-
- rect->freq = res.tv_sec + res.tv_usec / 1000000.;
- rect->freq /= count;
- rect->freq = 1. / rect->freq;
- }
- }
- return has_dirty;
-}
-
-double vnc_update_freq(VncState *vs, int x, int y, int w, int h)
-{
- int i, j;
- double total = 0;
- int num = 0;
-
- x = (x / VNC_STAT_RECT) * VNC_STAT_RECT;
- y = (y / VNC_STAT_RECT) * VNC_STAT_RECT;
-
- for (j = y; j <= y + h; j += VNC_STAT_RECT) {
- for (i = x; i <= x + w; i += VNC_STAT_RECT) {
- total += vnc_stat_rect(vs->vd, i, j)->freq;
- num++;
- }
- }
-
- if (num) {
- return total / num;
- } else {
- return 0;
- }
-}
-
-static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
-{
- VncRectStat *rect;
-
- rect = vnc_stat_rect(vd, x, y);
- if (rect->updated) {
- return ;
- }
- rect->times[rect->idx] = *tv;
- rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times);
- rect->updated = true;
-}
-
-static int vnc_refresh_server_surface(VncDisplay *vd)
-{
- int width = MIN(pixman_image_get_width(vd->guest.fb),
- pixman_image_get_width(vd->server));
- int height = MIN(pixman_image_get_height(vd->guest.fb),
- pixman_image_get_height(vd->server));
- int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
- uint8_t *guest_row0 = NULL, *server_row0;
- VncState *vs;
- int has_dirty = 0;
- pixman_image_t *tmpbuf = NULL;
-
- struct timeval tv = { 0, 0 };
-
- if (!vd->non_adaptive) {
- gettimeofday(&tv, NULL);
- has_dirty = vnc_update_stats(vd, &tv);
- }
-
- /*
- * Walk through the guest dirty map.
- * Check and copy modified bits from guest to server surface.
- * Update server dirty map.
- */
- server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
- server_stride = guest_stride = guest_ll =
- pixman_image_get_stride(vd->server);
- cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
- server_stride);
- if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
- int width = pixman_image_get_width(vd->server);
- tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
- } else {
- int guest_bpp =
- PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
- guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
- guest_stride = pixman_image_get_stride(vd->guest.fb);
- guest_ll = pixman_image_get_width(vd->guest.fb) * ((guest_bpp + 7) / 8);
- }
- line_bytes = MIN(server_stride, guest_ll);
-
- for (;;) {
- int x;
- uint8_t *guest_ptr, *server_ptr;
- unsigned long offset = find_next_bit((unsigned long *) &vd->guest.dirty,
- height * VNC_DIRTY_BPL(&vd->guest),
- y * VNC_DIRTY_BPL(&vd->guest));
- if (offset == height * VNC_DIRTY_BPL(&vd->guest)) {
- /* no more dirty bits */
- break;
- }
- y = offset / VNC_DIRTY_BPL(&vd->guest);
- x = offset % VNC_DIRTY_BPL(&vd->guest);
-
- server_ptr = server_row0 + y * server_stride + x * cmp_bytes;
-
- if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
- qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
- guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
- } else {
- guest_ptr = guest_row0 + y * guest_stride;
- }
- guest_ptr += x * cmp_bytes;
-
- for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT);
- x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
- int _cmp_bytes = cmp_bytes;
- if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
- continue;
- }
- if ((x + 1) * cmp_bytes > line_bytes) {
- _cmp_bytes = line_bytes - x * cmp_bytes;
- }
- assert(_cmp_bytes >= 0);
- if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
- continue;
- }
- memcpy(server_ptr, guest_ptr, _cmp_bytes);
- if (!vd->non_adaptive) {
- vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT,
- y, &tv);
- }
- QTAILQ_FOREACH(vs, &vd->clients, next) {
- set_bit(x, vs->dirty[y]);
- }
- has_dirty++;
- }
-
- y++;
- }
- qemu_pixman_image_unref(tmpbuf);
- return has_dirty;
-}
-
-static void vnc_refresh(DisplayChangeListener *dcl)
-{
- VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
- VncState *vs, *vn;
- int has_dirty, rects = 0;
-
- if (QTAILQ_EMPTY(&vd->clients)) {
- update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
- return;
- }
-
- graphic_hw_update(vd->dcl.con);
-
- if (vnc_trylock_display(vd)) {
- update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
- return;
- }
-
- has_dirty = vnc_refresh_server_surface(vd);
- vnc_unlock_display(vd);
-
- QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
- rects += vnc_update_client(vs, has_dirty, false);
- /* vs might be free()ed here */
- }
-
- if (has_dirty && rects) {
- vd->dcl.update_interval /= 2;
- if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
- vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
- }
- } else {
- vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
- if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
- vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
- }
- }
-}
-
-static void vnc_connect(VncDisplay *vd, QIOChannelSocket *sioc,
- bool skipauth, bool websocket)
-{
- VncState *vs = g_new0(VncState, 1);
- int i;
-
- vs->sioc = sioc;
- object_ref(OBJECT(vs->sioc));
- vs->ioc = QIO_CHANNEL(sioc);
- object_ref(OBJECT(vs->ioc));
- vs->vd = vd;
-
- buffer_init(&vs->input, "vnc-input/%p", sioc);
- buffer_init(&vs->output, "vnc-output/%p", sioc);
- buffer_init(&vs->jobs_buffer, "vnc-jobs_buffer/%p", sioc);
-
- buffer_init(&vs->tight.tight, "vnc-tight/%p", sioc);
- buffer_init(&vs->tight.zlib, "vnc-tight-zlib/%p", sioc);
- buffer_init(&vs->tight.gradient, "vnc-tight-gradient/%p", sioc);
-#ifdef CONFIG_VNC_JPEG
- buffer_init(&vs->tight.jpeg, "vnc-tight-jpeg/%p", sioc);
-#endif
-#ifdef CONFIG_VNC_PNG
- buffer_init(&vs->tight.png, "vnc-tight-png/%p", sioc);
-#endif
- buffer_init(&vs->zlib.zlib, "vnc-zlib/%p", sioc);
- buffer_init(&vs->zrle.zrle, "vnc-zrle/%p", sioc);
- buffer_init(&vs->zrle.fb, "vnc-zrle-fb/%p", sioc);
- buffer_init(&vs->zrle.zlib, "vnc-zrle-zlib/%p", sioc);
-
- if (skipauth) {
- vs->auth = VNC_AUTH_NONE;
- vs->subauth = VNC_AUTH_INVALID;
- } else {
- if (websocket) {
- vs->auth = vd->ws_auth;
- vs->subauth = VNC_AUTH_INVALID;
- } else {
- vs->auth = vd->auth;
- vs->subauth = vd->subauth;
- }
- }
- VNC_DEBUG("Client sioc=%p ws=%d auth=%d subauth=%d\n",
- sioc, websocket, vs->auth, vs->subauth);
-
- vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
- for (i = 0; i < VNC_STAT_ROWS; ++i) {
- vs->lossy_rect[i] = g_new0(uint8_t, VNC_STAT_COLS);
- }
-
- VNC_DEBUG("New client on socket %p\n", vs->sioc);
- update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
- qio_channel_set_blocking(vs->ioc, false, NULL);
- if (websocket) {
- vs->websocket = 1;
- if (vd->ws_tls) {
- vs->ioc_tag = qio_channel_add_watch(
- vs->ioc, G_IO_IN, vncws_tls_handshake_io, vs, NULL);
- } else {
- vs->ioc_tag = qio_channel_add_watch(
- vs->ioc, G_IO_IN, vncws_handshake_io, vs, NULL);
- }
- } else {
- vs->ioc_tag = qio_channel_add_watch(
- vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
- }
-
- vnc_client_cache_addr(vs);
- vnc_qmp_event(vs, QAPI_EVENT_VNC_CONNECTED);
- vnc_set_share_mode(vs, VNC_SHARE_MODE_CONNECTING);
-
- if (!vs->websocket) {
- vnc_init_state(vs);
- }
-
- if (vd->num_connecting > vd->connections_limit) {
- QTAILQ_FOREACH(vs, &vd->clients, next) {
- if (vs->share_mode == VNC_SHARE_MODE_CONNECTING) {
- vnc_disconnect_start(vs);
- return;
- }
- }
- }
-}
-
-void vnc_init_state(VncState *vs)
-{
- vs->initialized = true;
- VncDisplay *vd = vs->vd;
- bool first_client = QTAILQ_EMPTY(&vd->clients);
-
- vs->last_x = -1;
- vs->last_y = -1;
-
- vs->as.freq = 44100;
- vs->as.nchannels = 2;
- vs->as.fmt = AUD_FMT_S16;
- vs->as.endianness = 0;
-
- qemu_mutex_init(&vs->output_mutex);
- vs->bh = qemu_bh_new(vnc_jobs_bh, vs);
-
- QTAILQ_INSERT_TAIL(&vd->clients, vs, next);
- if (first_client) {
- vnc_update_server_surface(vd);
- }
-
- graphic_hw_update(vd->dcl.con);
-
- vnc_write(vs, "RFB 003.008\n", 12);
- vnc_flush(vs);
- vnc_read_when(vs, protocol_version, 12);
- reset_keys(vs);
- if (vs->vd->lock_key_sync)
- vs->led = qemu_add_led_event_handler(kbd_leds, vs);
-
- vs->mouse_mode_notifier.notify = check_pointer_type_change;
- qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
-
- /* vs might be free()ed here */
-}
-
-static gboolean vnc_listen_io(QIOChannel *ioc,
- GIOCondition condition,
- void *opaque)
-{
- VncDisplay *vs = opaque;
- QIOChannelSocket *sioc = NULL;
- Error *err = NULL;
-
- /* Catch-up */
- graphic_hw_update(vs->dcl.con);
- sioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc), &err);
- if (sioc != NULL) {
- qio_channel_set_delay(QIO_CHANNEL(sioc), false);
- vnc_connect(vs, sioc, false,
- ioc != QIO_CHANNEL(vs->lsock));
- object_unref(OBJECT(sioc));
- } else {
- /* client probably closed connection before we got there */
- error_free(err);
- }
-
- return TRUE;
-}
-
-static const DisplayChangeListenerOps dcl_ops = {
- .dpy_name = "vnc",
- .dpy_refresh = vnc_refresh,
- .dpy_gfx_copy = vnc_dpy_copy,
- .dpy_gfx_update = vnc_dpy_update,
- .dpy_gfx_switch = vnc_dpy_switch,
- .dpy_gfx_check_format = qemu_pixman_check_format,
- .dpy_mouse_set = vnc_mouse_set,
- .dpy_cursor_define = vnc_dpy_cursor_define,
-};
-
-void vnc_display_init(const char *id)
-{
- VncDisplay *vs;
-
- if (vnc_display_find(id) != NULL) {
- return;
- }
- vs = g_malloc0(sizeof(*vs));
-
- vs->id = strdup(id);
- QTAILQ_INSERT_TAIL(&vnc_displays, vs, next);
-
- QTAILQ_INIT(&vs->clients);
- vs->expires = TIME_MAX;
-
- if (keyboard_layout) {
- trace_vnc_key_map_init(keyboard_layout);
- vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
- } else {
- vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
- }
-
- if (!vs->kbd_layout)
- exit(1);
-
- qemu_mutex_init(&vs->mutex);
- vnc_start_worker_thread();
-
- vs->dcl.ops = &dcl_ops;
- register_displaychangelistener(&vs->dcl);
-}
-
-
-static void vnc_display_close(VncDisplay *vs)
-{
- if (!vs)
- return;
- vs->enabled = false;
- vs->is_unix = false;
- if (vs->lsock != NULL) {
- if (vs->lsock_tag) {
- g_source_remove(vs->lsock_tag);
- }
- object_unref(OBJECT(vs->lsock));
- vs->lsock = NULL;
- }
- vs->ws_enabled = false;
- if (vs->lwebsock != NULL) {
- if (vs->lwebsock_tag) {
- g_source_remove(vs->lwebsock_tag);
- }
- object_unref(OBJECT(vs->lwebsock));
- vs->lwebsock = NULL;
- }
- vs->auth = VNC_AUTH_INVALID;
- vs->subauth = VNC_AUTH_INVALID;
- if (vs->tlscreds) {
- object_unparent(OBJECT(vs->tlscreds));
- vs->tlscreds = NULL;
- }
- g_free(vs->tlsaclname);
- vs->tlsaclname = NULL;
-}
-
-int vnc_display_password(const char *id, const char *password)
-{
- VncDisplay *vs = vnc_display_find(id);
-
- if (!vs) {
- return -EINVAL;
- }
- if (vs->auth == VNC_AUTH_NONE) {
- error_printf_unless_qmp("If you want use passwords please enable "
- "password auth using '-vnc ${dpy},password'.");
- return -EINVAL;
- }
-
- g_free(vs->password);
- vs->password = g_strdup(password);
-
- return 0;
-}
-
-int vnc_display_pw_expire(const char *id, time_t expires)
-{
- VncDisplay *vs = vnc_display_find(id);
-
- if (!vs) {
- return -EINVAL;
- }
-
- vs->expires = expires;
- return 0;
-}
-
-char *vnc_display_local_addr(const char *id)
-{
- VncDisplay *vs = vnc_display_find(id);
- SocketAddress *addr;
- char *ret;
- Error *err = NULL;
-
- assert(vs);
-
- addr = qio_channel_socket_get_local_address(vs->lsock, &err);
- if (!addr) {
- return NULL;
- }
-
- if (addr->type != SOCKET_ADDRESS_KIND_INET) {
- qapi_free_SocketAddress(addr);
- return NULL;
- }
- ret = g_strdup_printf("%s;%s", addr->u.inet.data->host,
- addr->u.inet.data->port);
- qapi_free_SocketAddress(addr);
-
- return ret;
-}
-
-static QemuOptsList qemu_vnc_opts = {
- .name = "vnc",
- .head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
- .implied_opt_name = "vnc",
- .desc = {
- {
- .name = "vnc",
- .type = QEMU_OPT_STRING,
- },{
- .name = "websocket",
- .type = QEMU_OPT_STRING,
- },{
- .name = "tls-creds",
- .type = QEMU_OPT_STRING,
- },{
- /* Deprecated in favour of tls-creds */
- .name = "x509",
- .type = QEMU_OPT_STRING,
- },{
- .name = "share",
- .type = QEMU_OPT_STRING,
- },{
- .name = "display",
- .type = QEMU_OPT_STRING,
- },{
- .name = "head",
- .type = QEMU_OPT_NUMBER,
- },{
- .name = "connections",
- .type = QEMU_OPT_NUMBER,
- },{
- .name = "to",
- .type = QEMU_OPT_NUMBER,
- },{
- .name = "ipv4",
- .type = QEMU_OPT_BOOL,
- },{
- .name = "ipv6",
- .type = QEMU_OPT_BOOL,
- },{
- .name = "password",
- .type = QEMU_OPT_BOOL,
- },{
- .name = "reverse",
- .type = QEMU_OPT_BOOL,
- },{
- .name = "lock-key-sync",
- .type = QEMU_OPT_BOOL,
- },{
- .name = "sasl",
- .type = QEMU_OPT_BOOL,
- },{
- /* Deprecated in favour of tls-creds */
- .name = "tls",
- .type = QEMU_OPT_BOOL,
- },{
- /* Deprecated in favour of tls-creds */
- .name = "x509verify",
- .type = QEMU_OPT_STRING,
- },{
- .name = "acl",
- .type = QEMU_OPT_BOOL,
- },{
- .name = "lossy",
- .type = QEMU_OPT_BOOL,
- },{
- .name = "non-adaptive",
- .type = QEMU_OPT_BOOL,
- },
- { /* end of list */ }
- },
-};
-
-
-static int
-vnc_display_setup_auth(VncDisplay *vs,
- bool password,
- bool sasl,
- bool websocket,
- Error **errp)
-{
- /*
- * We have a choice of 3 authentication options
- *
- * 1. none
- * 2. vnc
- * 3. sasl
- *
- * The channel can be run in 2 modes
- *
- * 1. clear
- * 2. tls
- *
- * And TLS can use 2 types of credentials
- *
- * 1. anon
- * 2. x509
- *
- * We thus have 9 possible logical combinations
- *
- * 1. clear + none
- * 2. clear + vnc
- * 3. clear + sasl
- * 4. tls + anon + none
- * 5. tls + anon + vnc
- * 6. tls + anon + sasl
- * 7. tls + x509 + none
- * 8. tls + x509 + vnc
- * 9. tls + x509 + sasl
- *
- * These need to be mapped into the VNC auth schemes
- * in an appropriate manner. In regular VNC, all the
- * TLS options get mapped into VNC_AUTH_VENCRYPT
- * sub-auth types.
- *
- * In websockets, the https:// protocol already provides
- * TLS support, so there is no need to make use of the
- * VeNCrypt extension. Furthermore, websockets browser
- * clients could not use VeNCrypt even if they wanted to,
- * as they cannot control when the TLS handshake takes
- * place. Thus there is no option but to rely on https://,
- * meaning combinations 4->6 and 7->9 will be mapped to
- * VNC auth schemes in the same way as combos 1->3.
- *
- * Regardless of fact that we have a different mapping to
- * VNC auth mechs for plain VNC vs websockets VNC, the end
- * result has the same security characteristics.
- */
- if (password) {
- if (vs->tlscreds) {
- vs->auth = VNC_AUTH_VENCRYPT;
- if (websocket) {
- vs->ws_tls = true;
- }
- if (object_dynamic_cast(OBJECT(vs->tlscreds),
- TYPE_QCRYPTO_TLS_CREDS_X509)) {
- VNC_DEBUG("Initializing VNC server with x509 password auth\n");
- vs->subauth = VNC_AUTH_VENCRYPT_X509VNC;
- } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
- TYPE_QCRYPTO_TLS_CREDS_ANON)) {
- VNC_DEBUG("Initializing VNC server with TLS password auth\n");
- vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC;
- } else {
- error_setg(errp,
- "Unsupported TLS cred type %s",
- object_get_typename(OBJECT(vs->tlscreds)));
- return -1;
- }
- } else {
- VNC_DEBUG("Initializing VNC server with password auth\n");
- vs->auth = VNC_AUTH_VNC;
- vs->subauth = VNC_AUTH_INVALID;
- }
- if (websocket) {
- vs->ws_auth = VNC_AUTH_VNC;
- } else {
- vs->ws_auth = VNC_AUTH_INVALID;
- }
- } else if (sasl) {
- if (vs->tlscreds) {
- vs->auth = VNC_AUTH_VENCRYPT;
- if (websocket) {
- vs->ws_tls = true;
- }
- if (object_dynamic_cast(OBJECT(vs->tlscreds),
- TYPE_QCRYPTO_TLS_CREDS_X509)) {
- VNC_DEBUG("Initializing VNC server with x509 SASL auth\n");
- vs->subauth = VNC_AUTH_VENCRYPT_X509SASL;
- } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
- TYPE_QCRYPTO_TLS_CREDS_ANON)) {
- VNC_DEBUG("Initializing VNC server with TLS SASL auth\n");
- vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL;
- } else {
- error_setg(errp,
- "Unsupported TLS cred type %s",
- object_get_typename(OBJECT(vs->tlscreds)));
- return -1;
- }
- } else {
- VNC_DEBUG("Initializing VNC server with SASL auth\n");
- vs->auth = VNC_AUTH_SASL;
- vs->subauth = VNC_AUTH_INVALID;
- }
- if (websocket) {
- vs->ws_auth = VNC_AUTH_SASL;
- } else {
- vs->ws_auth = VNC_AUTH_INVALID;
- }
- } else {
- if (vs->tlscreds) {
- vs->auth = VNC_AUTH_VENCRYPT;
- if (websocket) {
- vs->ws_tls = true;
- }
- if (object_dynamic_cast(OBJECT(vs->tlscreds),
- TYPE_QCRYPTO_TLS_CREDS_X509)) {
- VNC_DEBUG("Initializing VNC server with x509 no auth\n");
- vs->subauth = VNC_AUTH_VENCRYPT_X509NONE;
- } else if (object_dynamic_cast(OBJECT(vs->tlscreds),
- TYPE_QCRYPTO_TLS_CREDS_ANON)) {
- VNC_DEBUG("Initializing VNC server with TLS no auth\n");
- vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE;
- } else {
- error_setg(errp,
- "Unsupported TLS cred type %s",
- object_get_typename(OBJECT(vs->tlscreds)));
- return -1;
- }
- } else {
- VNC_DEBUG("Initializing VNC server with no auth\n");
- vs->auth = VNC_AUTH_NONE;
- vs->subauth = VNC_AUTH_INVALID;
- }
- if (websocket) {
- vs->ws_auth = VNC_AUTH_NONE;
- } else {
- vs->ws_auth = VNC_AUTH_INVALID;
- }
- }
- return 0;
-}
-
-
-/*
- * Handle back compat with old CLI syntax by creating some
- * suitable QCryptoTLSCreds objects
- */
-static QCryptoTLSCreds *
-vnc_display_create_creds(bool x509,
- bool x509verify,
- const char *dir,
- const char *id,
- Error **errp)
-{
- gchar *credsid = g_strdup_printf("tlsvnc%s", id);
- Object *parent = object_get_objects_root();
- Object *creds;
- Error *err = NULL;
-
- if (x509) {
- creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_X509,
- parent,
- credsid,
- &err,
- "endpoint", "server",
- "dir", dir,
- "verify-peer", x509verify ? "yes" : "no",
- NULL);
- } else {
- creds = object_new_with_props(TYPE_QCRYPTO_TLS_CREDS_ANON,
- parent,
- credsid,
- &err,
- "endpoint", "server",
- NULL);
- }
-
- g_free(credsid);
-
- if (err) {
- error_propagate(errp, err);
- return NULL;
- }
-
- return QCRYPTO_TLS_CREDS(creds);
-}
-
-
-void vnc_display_open(const char *id, Error **errp)
-{
- VncDisplay *vs = vnc_display_find(id);
- QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
- SocketAddress *saddr = NULL, *wsaddr = NULL;
- const char *share, *device_id;
- QemuConsole *con;
- bool password = false;
- bool reverse = false;
- const char *vnc;
- char *h;
- const char *credid;
- bool sasl = false;
-#ifdef CONFIG_VNC_SASL
- int saslErr;
-#endif
- int acl = 0;
- int lock_key_sync = 1;
-
- if (!vs) {
- error_setg(errp, "VNC display not active");
- return;
- }
- vnc_display_close(vs);
-
- if (!opts) {
- return;
- }
- vnc = qemu_opt_get(opts, "vnc");
- if (!vnc || strcmp(vnc, "none") == 0) {
- return;
- }
-
- h = strrchr(vnc, ':');
- if (h) {
- size_t hlen = h - vnc;
-
- const char *websocket = qemu_opt_get(opts, "websocket");
- int to = qemu_opt_get_number(opts, "to", 0);
- bool has_ipv4 = qemu_opt_get(opts, "ipv4");
- bool has_ipv6 = qemu_opt_get(opts, "ipv6");
- bool ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
- bool ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
-
- saddr = g_new0(SocketAddress, 1);
- if (websocket) {
- if (!qcrypto_hash_supports(QCRYPTO_HASH_ALG_SHA1)) {
- error_setg(errp,
- "SHA1 hash support is required for websockets");
- goto fail;
- }
-
- wsaddr = g_new0(SocketAddress, 1);
- vs->ws_enabled = true;
- }
-
- if (strncmp(vnc, "unix:", 5) == 0) {
- saddr->type = SOCKET_ADDRESS_KIND_UNIX;
- saddr->u.q_unix.data = g_new0(UnixSocketAddress, 1);
- saddr->u.q_unix.data->path = g_strdup(vnc + 5);
-
- if (vs->ws_enabled) {
- error_setg(errp, "UNIX sockets not supported with websock");
- goto fail;
- }
- } else {
- unsigned long long baseport;
- InetSocketAddress *inet;
- saddr->type = SOCKET_ADDRESS_KIND_INET;
- inet = saddr->u.inet.data = g_new0(InetSocketAddress, 1);
- if (vnc[0] == '[' && vnc[hlen - 1] == ']') {
- inet->host = g_strndup(vnc + 1, hlen - 2);
- } else {
- inet->host = g_strndup(vnc, hlen);
- }
- if (parse_uint_full(h + 1, &baseport, 10) < 0) {
- error_setg(errp, "can't convert to a number: %s", h + 1);
- goto fail;
- }
- if (baseport > 65535 ||
- baseport + 5900 > 65535) {
- error_setg(errp, "port %s out of range", h + 1);
- goto fail;
- }
- inet->port = g_strdup_printf(
- "%d", (int)baseport + 5900);
-
- if (to) {
- inet->has_to = true;
- inet->to = to + 5900;
- }
- inet->ipv4 = ipv4;
- inet->has_ipv4 = has_ipv4;
- inet->ipv6 = ipv6;
- inet->has_ipv6 = has_ipv6;
-
- if (vs->ws_enabled) {
- wsaddr->type = SOCKET_ADDRESS_KIND_INET;
- inet = wsaddr->u.inet.data = g_new0(InetSocketAddress, 1);
- inet->host = g_strdup(saddr->u.inet.data->host);
- inet->port = g_strdup(websocket);
-
- if (to) {
- inet->has_to = true;
- inet->to = to;
- }
- inet->ipv4 = ipv4;
- inet->has_ipv4 = has_ipv4;
- inet->ipv6 = ipv6;
- inet->has_ipv6 = has_ipv6;
- }
- }
- } else {
- error_setg(errp, "no vnc port specified");
- goto fail;
- }
-
- password = qemu_opt_get_bool(opts, "password", false);
- if (password) {
- if (fips_get_state()) {
- error_setg(errp,
- "VNC password auth disabled due to FIPS mode, "
- "consider using the VeNCrypt or SASL authentication "
- "methods as an alternative");
- goto fail;
- }
- if (!qcrypto_cipher_supports(
- QCRYPTO_CIPHER_ALG_DES_RFB)) {
- error_setg(errp,
- "Cipher backend does not support DES RFB algorithm");
- goto fail;
- }
- }
-
- reverse = qemu_opt_get_bool(opts, "reverse", false);
- lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
- sasl = qemu_opt_get_bool(opts, "sasl", false);
-#ifndef CONFIG_VNC_SASL
- if (sasl) {
- error_setg(errp, "VNC SASL auth requires cyrus-sasl support");
- goto fail;
- }
-#endif /* CONFIG_VNC_SASL */
- credid = qemu_opt_get(opts, "tls-creds");
- if (credid) {
- Object *creds;
- if (qemu_opt_get(opts, "tls") ||
- qemu_opt_get(opts, "x509") ||
- qemu_opt_get(opts, "x509verify")) {
- error_setg(errp,
- "'tls-creds' parameter is mutually exclusive with "
- "'tls', 'x509' and 'x509verify' parameters");
- goto fail;
- }
-
- creds = object_resolve_path_component(
- object_get_objects_root(), credid);
- if (!creds) {
- error_setg(errp, "No TLS credentials with id '%s'",
- credid);
- goto fail;
- }
- vs->tlscreds = (QCryptoTLSCreds *)
- object_dynamic_cast(creds,
- TYPE_QCRYPTO_TLS_CREDS);
- if (!vs->tlscreds) {
- error_setg(errp, "Object with id '%s' is not TLS credentials",
- credid);
- goto fail;
- }
- object_ref(OBJECT(vs->tlscreds));
-
- if (vs->tlscreds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
- error_setg(errp,
- "Expecting TLS credentials with a server endpoint");
- goto fail;
- }
- } else {
- const char *path;
- bool tls = false, x509 = false, x509verify = false;
- tls = qemu_opt_get_bool(opts, "tls", false);
- if (tls) {
- path = qemu_opt_get(opts, "x509");
-
- if (path) {
- x509 = true;
- } else {
- path = qemu_opt_get(opts, "x509verify");
- if (path) {
- x509 = true;
- x509verify = true;
- }
- }
- vs->tlscreds = vnc_display_create_creds(x509,
- x509verify,
- path,
- vs->id,
- errp);
- if (!vs->tlscreds) {
- goto fail;
- }
- }
- }
- acl = qemu_opt_get_bool(opts, "acl", false);
-
- share = qemu_opt_get(opts, "share");
- if (share) {
- if (strcmp(share, "ignore") == 0) {
- vs->share_policy = VNC_SHARE_POLICY_IGNORE;
- } else if (strcmp(share, "allow-exclusive") == 0) {
- vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
- } else if (strcmp(share, "force-shared") == 0) {
- vs->share_policy = VNC_SHARE_POLICY_FORCE_SHARED;
- } else {
- error_setg(errp, "unknown vnc share= option");
- goto fail;
- }
- } else {
- vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
- }
- vs->connections_limit = qemu_opt_get_number(opts, "connections", 32);
-
-#ifdef CONFIG_VNC_JPEG
- vs->lossy = qemu_opt_get_bool(opts, "lossy", false);
-#endif
- vs->non_adaptive = qemu_opt_get_bool(opts, "non-adaptive", false);
- /* adaptive updates are only used with tight encoding and
- * if lossy updates are enabled so we can disable all the
- * calculations otherwise */
- if (!vs->lossy) {
- vs->non_adaptive = true;
- }
-
- if (acl) {
- if (strcmp(vs->id, "default") == 0) {
- vs->tlsaclname = g_strdup("vnc.x509dname");
- } else {
- vs->tlsaclname = g_strdup_printf("vnc.%s.x509dname", vs->id);
- }
- qemu_acl_init(vs->tlsaclname);
- }
-#ifdef CONFIG_VNC_SASL
- if (acl && sasl) {
- char *aclname;
-
- if (strcmp(vs->id, "default") == 0) {
- aclname = g_strdup("vnc.username");
- } else {
- aclname = g_strdup_printf("vnc.%s.username", vs->id);
- }
- vs->sasl.acl = qemu_acl_init(aclname);
- g_free(aclname);
- }
-#endif
-
- if (vnc_display_setup_auth(vs, password, sasl, vs->ws_enabled, errp) < 0) {
- goto fail;
- }
-
-#ifdef CONFIG_VNC_SASL
- if ((saslErr = sasl_server_init(NULL, "qemu")) != SASL_OK) {
- error_setg(errp, "Failed to initialize SASL auth: %s",
- sasl_errstring(saslErr, NULL, NULL));
- goto fail;
- }
-#endif
- vs->lock_key_sync = lock_key_sync;
-
- device_id = qemu_opt_get(opts, "display");
- if (device_id) {
- int head = qemu_opt_get_number(opts, "head", 0);
- Error *err = NULL;
-
- con = qemu_console_lookup_by_device_name(device_id, head, &err);
- if (err) {
- error_propagate(errp, err);
- goto fail;
- }
- } else {
- con = NULL;
- }
-
- if (con != vs->dcl.con) {
- unregister_displaychangelistener(&vs->dcl);
- vs->dcl.con = con;
- register_displaychangelistener(&vs->dcl);
- }
-
- if (reverse) {
- /* connect to viewer */
- QIOChannelSocket *sioc = NULL;
- vs->lsock = NULL;
- vs->lwebsock = NULL;
- if (vs->ws_enabled) {
- error_setg(errp, "Cannot use websockets in reverse mode");
- goto fail;
- }
- vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
- sioc = qio_channel_socket_new();
- if (qio_channel_socket_connect_sync(sioc, saddr, errp) < 0) {
- goto fail;
- }
- vnc_connect(vs, sioc, false, false);
- object_unref(OBJECT(sioc));
- } else {
- vs->lsock = qio_channel_socket_new();
- if (qio_channel_socket_listen_sync(vs->lsock, saddr, errp) < 0) {
- goto fail;
- }
- vs->is_unix = saddr->type == SOCKET_ADDRESS_KIND_UNIX;
- vs->enabled = true;
-
- if (vs->ws_enabled) {
- vs->lwebsock = qio_channel_socket_new();
- if (qio_channel_socket_listen_sync(vs->lwebsock,
- wsaddr, errp) < 0) {
- object_unref(OBJECT(vs->lsock));
- vs->lsock = NULL;
- goto fail;
- }
- }
-
- vs->lsock_tag = qio_channel_add_watch(
- QIO_CHANNEL(vs->lsock),
- G_IO_IN, vnc_listen_io, vs, NULL);
- if (vs->ws_enabled) {
- vs->lwebsock_tag = qio_channel_add_watch(
- QIO_CHANNEL(vs->lwebsock),
- G_IO_IN, vnc_listen_io, vs, NULL);
- }
- }
-
- qapi_free_SocketAddress(saddr);
- qapi_free_SocketAddress(wsaddr);
- return;
-
-fail:
- qapi_free_SocketAddress(saddr);
- qapi_free_SocketAddress(wsaddr);
- vs->enabled = false;
- vs->ws_enabled = false;
-}
-
-void vnc_display_add_client(const char *id, int csock, bool skipauth)
-{
- VncDisplay *vs = vnc_display_find(id);
- QIOChannelSocket *sioc;
-
- if (!vs) {
- return;
- }
-
- sioc = qio_channel_socket_new_fd(csock, NULL);
- if (sioc) {
- vnc_connect(vs, sioc, skipauth, false);
- object_unref(OBJECT(sioc));
- }
-}
-
-static void vnc_auto_assign_id(QemuOptsList *olist, QemuOpts *opts)
-{
- int i = 2;
- char *id;
-
- id = g_strdup("default");
- while (qemu_opts_find(olist, id)) {
- g_free(id);
- id = g_strdup_printf("vnc%d", i++);
- }
- qemu_opts_set_id(opts, id);
-}
-
-QemuOpts *vnc_parse(const char *str, Error **errp)
-{
- QemuOptsList *olist = qemu_find_opts("vnc");
- QemuOpts *opts = qemu_opts_parse(olist, str, true, errp);
- const char *id;
-
- if (!opts) {
- return NULL;
- }
-
- id = qemu_opts_id(opts);
- if (!id) {
- /* auto-assign id if not present */
- vnc_auto_assign_id(olist, opts);
- }
- return opts;
-}
-
-int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp)
-{
- Error *local_err = NULL;
- char *id = (char *)qemu_opts_id(opts);
-
- assert(id);
- vnc_display_init(id);
- vnc_display_open(id, &local_err);
- if (local_err != NULL) {
- error_reportf_err(local_err, "Failed to start VNC server: ");
- exit(1);
- }
- return 0;
-}
-
-static void vnc_register_config(void)
-{
- qemu_add_opts(&qemu_vnc_opts);
-}
-opts_init(vnc_register_config);
diff --git a/qemu/ui/vnc.h b/qemu/ui/vnc.h
deleted file mode 100644
index 81a326116..000000000
--- a/qemu/ui/vnc.h
+++ /dev/null
@@ -1,579 +0,0 @@
-/*
- * QEMU VNC display driver
- *
- * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
- * Copyright (C) 2006 Fabrice Bellard
- * Copyright (C) 2009 Red Hat, Inc
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef __QEMU_VNC_H
-#define __QEMU_VNC_H
-
-#include "qemu-common.h"
-#include "qemu/queue.h"
-#include "qemu/thread.h"
-#include "ui/console.h"
-#include "audio/audio.h"
-#include "qemu/bitmap.h"
-#include "crypto/tlssession.h"
-#include "qemu/buffer.h"
-#include "io/channel-socket.h"
-#include "io/channel-tls.h"
-#include <zlib.h>
-
-#include "keymaps.h"
-#include "vnc-palette.h"
-#include "vnc-enc-zrle.h"
-#include "qapi-types.h"
-
-// #define _VNC_DEBUG 1
-
-#ifdef _VNC_DEBUG
-#define VNC_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
-#else
-#define VNC_DEBUG(fmt, ...) do { } while (0)
-#endif
-
-/*****************************************************************************
- *
- * Core data structures
- *
- *****************************************************************************/
-
-typedef struct VncState VncState;
-typedef struct VncJob VncJob;
-typedef struct VncRect VncRect;
-typedef struct VncRectEntry VncRectEntry;
-
-typedef int VncReadEvent(VncState *vs, uint8_t *data, size_t len);
-
-typedef void VncWritePixels(VncState *vs, void *data, int size);
-
-typedef void VncSendHextileTile(VncState *vs,
- int x, int y, int w, int h,
- void *last_bg,
- void *last_fg,
- int *has_bg, int *has_fg);
-
-/* VNC_DIRTY_PIXELS_PER_BIT is the number of dirty pixels represented
- * by one bit in the dirty bitmap, should be a power of 2 */
-#define VNC_DIRTY_PIXELS_PER_BIT 16
-
-/* VNC_MAX_WIDTH must be a multiple of VNC_DIRTY_PIXELS_PER_BIT. */
-
-#define VNC_MAX_WIDTH ROUND_UP(2560, VNC_DIRTY_PIXELS_PER_BIT)
-#define VNC_MAX_HEIGHT 2048
-
-/* VNC_DIRTY_BITS is the number of bits in the dirty bitmap. */
-#define VNC_DIRTY_BITS (VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT)
-
-/* VNC_DIRTY_BPL (BPL = bits per line) might be greater than
- * VNC_DIRTY_BITS due to alignment */
-#define VNC_DIRTY_BPL(x) (sizeof((x)->dirty) / VNC_MAX_HEIGHT * BITS_PER_BYTE)
-
-#define VNC_STAT_RECT 64
-#define VNC_STAT_COLS (VNC_MAX_WIDTH / VNC_STAT_RECT)
-#define VNC_STAT_ROWS (VNC_MAX_HEIGHT / VNC_STAT_RECT)
-
-#define VNC_AUTH_CHALLENGE_SIZE 16
-
-typedef struct VncDisplay VncDisplay;
-
-#include "vnc-auth-vencrypt.h"
-#ifdef CONFIG_VNC_SASL
-#include "vnc-auth-sasl.h"
-#endif
-#include "vnc-ws.h"
-
-struct VncRectStat
-{
- /* time of last 10 updates, to find update frequency */
- struct timeval times[10];
- int idx;
-
- double freq; /* Update frequency (in Hz) */
- bool updated; /* Already updated during this refresh */
-};
-
-typedef struct VncRectStat VncRectStat;
-
-struct VncSurface
-{
- struct timeval last_freq_check;
- DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT],
- VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT);
- VncRectStat stats[VNC_STAT_ROWS][VNC_STAT_COLS];
- pixman_image_t *fb;
- pixman_format_code_t format;
-};
-
-typedef enum VncShareMode {
- VNC_SHARE_MODE_CONNECTING = 1,
- VNC_SHARE_MODE_SHARED,
- VNC_SHARE_MODE_EXCLUSIVE,
- VNC_SHARE_MODE_DISCONNECTED,
-} VncShareMode;
-
-typedef enum VncSharePolicy {
- VNC_SHARE_POLICY_IGNORE = 1,
- VNC_SHARE_POLICY_ALLOW_EXCLUSIVE,
- VNC_SHARE_POLICY_FORCE_SHARED,
-} VncSharePolicy;
-
-struct VncDisplay
-{
- QTAILQ_HEAD(, VncState) clients;
- int num_connecting;
- int num_shared;
- int num_exclusive;
- int connections_limit;
- VncSharePolicy share_policy;
- QIOChannelSocket *lsock;
- guint lsock_tag;
- QIOChannelSocket *lwebsock;
- guint lwebsock_tag;
- bool ws_enabled;
- DisplaySurface *ds;
- DisplayChangeListener dcl;
- kbd_layout_t *kbd_layout;
- int lock_key_sync;
- QemuMutex mutex;
-
- QEMUCursor *cursor;
- int cursor_msize;
- uint8_t *cursor_mask;
-
- struct VncSurface guest; /* guest visible surface (aka ds->surface) */
- pixman_image_t *server; /* vnc server surface */
-
- const char *id;
- QTAILQ_ENTRY(VncDisplay) next;
- bool enabled;
- bool is_unix;
- char *password;
- time_t expires;
- int auth;
- int subauth; /* Used by VeNCrypt */
- int ws_auth; /* Used by websockets */
- bool ws_tls; /* Used by websockets */
- bool lossy;
- bool non_adaptive;
- QCryptoTLSCreds *tlscreds;
- char *tlsaclname;
-#ifdef CONFIG_VNC_SASL
- VncDisplaySASL sasl;
-#endif
-};
-
-typedef struct VncTight {
- int type;
- uint8_t quality;
- uint8_t compression;
- uint8_t pixel24;
- Buffer tight;
- Buffer tmp;
- Buffer zlib;
- Buffer gradient;
-#ifdef CONFIG_VNC_JPEG
- Buffer jpeg;
-#endif
-#ifdef CONFIG_VNC_PNG
- Buffer png;
-#endif
- int levels[4];
- z_stream stream[4];
-} VncTight;
-
-typedef struct VncHextile {
- VncSendHextileTile *send_tile;
-} VncHextile;
-
-typedef struct VncZlib {
- Buffer zlib;
- Buffer tmp;
- z_stream stream;
- int level;
-} VncZlib;
-
-typedef struct VncZrle {
- int type;
- Buffer fb;
- Buffer zrle;
- Buffer tmp;
- Buffer zlib;
- z_stream stream;
- VncPalette palette;
-} VncZrle;
-
-typedef struct VncZywrle {
- int buf[VNC_ZRLE_TILE_WIDTH * VNC_ZRLE_TILE_HEIGHT];
-} VncZywrle;
-
-struct VncRect
-{
- int x;
- int y;
- int w;
- int h;
-};
-
-struct VncRectEntry
-{
- struct VncRect rect;
- QLIST_ENTRY(VncRectEntry) next;
-};
-
-struct VncJob
-{
- VncState *vs;
-
- QLIST_HEAD(, VncRectEntry) rectangles;
- QTAILQ_ENTRY(VncJob) next;
-};
-
-struct VncState
-{
- QIOChannelSocket *sioc; /* The underlying socket */
- QIOChannel *ioc; /* The channel currently used for I/O */
- guint ioc_tag;
- gboolean disconnecting;
-
- DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT], VNC_DIRTY_BITS);
- uint8_t **lossy_rect; /* Not an Array to avoid costly memcpy in
- * vnc-jobs-async.c */
-
- VncDisplay *vd;
- int need_update;
- int force_update;
- int has_dirty;
- uint32_t features;
- int absolute;
- int last_x;
- int last_y;
- uint32_t last_bmask;
- int client_width;
- int client_height;
- VncShareMode share_mode;
-
- uint32_t vnc_encoding;
-
- int major;
- int minor;
-
- int auth;
- int subauth; /* Used by VeNCrypt */
- char challenge[VNC_AUTH_CHALLENGE_SIZE];
- QCryptoTLSSession *tls; /* Borrowed pointer from channel, don't free */
-#ifdef CONFIG_VNC_SASL
- VncStateSASL sasl;
-#endif
- bool encode_ws;
- bool websocket;
-
- VncClientInfo *info;
-
- Buffer output;
- Buffer input;
- /* current output mode information */
- VncWritePixels *write_pixels;
- PixelFormat client_pf;
- pixman_format_code_t client_format;
- bool client_be;
-
- CaptureVoiceOut *audio_cap;
- struct audsettings as;
-
- VncReadEvent *read_handler;
- size_t read_handler_expect;
- /* input */
- uint8_t modifiers_state[256];
- QEMUPutLEDEntry *led;
-
- bool abort;
- bool initialized;
- QemuMutex output_mutex;
- QEMUBH *bh;
- Buffer jobs_buffer;
-
- /* Encoding specific, if you add something here, don't forget to
- * update vnc_async_encoding_start()
- */
- VncTight tight;
- VncZlib zlib;
- VncHextile hextile;
- VncZrle zrle;
- VncZywrle zywrle;
-
- Notifier mouse_mode_notifier;
-
- QTAILQ_ENTRY(VncState) next;
-};
-
-
-/*****************************************************************************
- *
- * Authentication modes
- *
- *****************************************************************************/
-
-enum {
- VNC_AUTH_INVALID = 0,
- VNC_AUTH_NONE = 1,
- VNC_AUTH_VNC = 2,
- VNC_AUTH_RA2 = 5,
- VNC_AUTH_RA2NE = 6,
- VNC_AUTH_TIGHT = 16,
- VNC_AUTH_ULTRA = 17,
- VNC_AUTH_TLS = 18, /* Supported in GTK-VNC & VINO */
- VNC_AUTH_VENCRYPT = 19, /* Supported in GTK-VNC & VeNCrypt */
- VNC_AUTH_SASL = 20, /* Supported in GTK-VNC & VINO */
-};
-
-enum {
- VNC_AUTH_VENCRYPT_PLAIN = 256,
- VNC_AUTH_VENCRYPT_TLSNONE = 257,
- VNC_AUTH_VENCRYPT_TLSVNC = 258,
- VNC_AUTH_VENCRYPT_TLSPLAIN = 259,
- VNC_AUTH_VENCRYPT_X509NONE = 260,
- VNC_AUTH_VENCRYPT_X509VNC = 261,
- VNC_AUTH_VENCRYPT_X509PLAIN = 262,
- VNC_AUTH_VENCRYPT_X509SASL = 263,
- VNC_AUTH_VENCRYPT_TLSSASL = 264,
-};
-
-
-/*****************************************************************************
- *
- * Encoding types
- *
- *****************************************************************************/
-
-#define VNC_ENCODING_RAW 0x00000000
-#define VNC_ENCODING_COPYRECT 0x00000001
-#define VNC_ENCODING_RRE 0x00000002
-#define VNC_ENCODING_CORRE 0x00000004
-#define VNC_ENCODING_HEXTILE 0x00000005
-#define VNC_ENCODING_ZLIB 0x00000006
-#define VNC_ENCODING_TIGHT 0x00000007
-#define VNC_ENCODING_ZLIBHEX 0x00000008
-#define VNC_ENCODING_TRLE 0x0000000f
-#define VNC_ENCODING_ZRLE 0x00000010
-#define VNC_ENCODING_ZYWRLE 0x00000011
-#define VNC_ENCODING_COMPRESSLEVEL0 0xFFFFFF00 /* -256 */
-#define VNC_ENCODING_QUALITYLEVEL0 0xFFFFFFE0 /* -32 */
-#define VNC_ENCODING_XCURSOR 0xFFFFFF10 /* -240 */
-#define VNC_ENCODING_RICH_CURSOR 0xFFFFFF11 /* -239 */
-#define VNC_ENCODING_POINTER_POS 0xFFFFFF18 /* -232 */
-#define VNC_ENCODING_LASTRECT 0xFFFFFF20 /* -224 */
-#define VNC_ENCODING_DESKTOPRESIZE 0xFFFFFF21 /* -223 */
-#define VNC_ENCODING_POINTER_TYPE_CHANGE 0XFFFFFEFF /* -257 */
-#define VNC_ENCODING_EXT_KEY_EVENT 0XFFFFFEFE /* -258 */
-#define VNC_ENCODING_AUDIO 0XFFFFFEFD /* -259 */
-#define VNC_ENCODING_TIGHT_PNG 0xFFFFFEFC /* -260 */
-#define VNC_ENCODING_LED_STATE 0XFFFFFEFB /* -261 */
-#define VNC_ENCODING_WMVi 0x574D5669
-
-/*****************************************************************************
- *
- * Other tight constants
- *
- *****************************************************************************/
-
-/*
- * Vendors known by TightVNC: standard VNC/RealVNC, TridiaVNC, and TightVNC.
- */
-
-#define VNC_TIGHT_CCB_RESET_MASK (0x0f)
-#define VNC_TIGHT_CCB_TYPE_MASK (0x0f << 4)
-#define VNC_TIGHT_CCB_TYPE_FILL (0x08 << 4)
-#define VNC_TIGHT_CCB_TYPE_JPEG (0x09 << 4)
-#define VNC_TIGHT_CCB_TYPE_PNG (0x0A << 4)
-#define VNC_TIGHT_CCB_BASIC_MAX (0x07 << 4)
-#define VNC_TIGHT_CCB_BASIC_ZLIB (0x03 << 4)
-#define VNC_TIGHT_CCB_BASIC_FILTER (0x04 << 4)
-
-/*****************************************************************************
- *
- * Features
- *
- *****************************************************************************/
-
-#define VNC_FEATURE_RESIZE 0
-#define VNC_FEATURE_HEXTILE 1
-#define VNC_FEATURE_POINTER_TYPE_CHANGE 2
-#define VNC_FEATURE_WMVI 3
-#define VNC_FEATURE_TIGHT 4
-#define VNC_FEATURE_ZLIB 5
-#define VNC_FEATURE_COPYRECT 6
-#define VNC_FEATURE_RICH_CURSOR 7
-#define VNC_FEATURE_TIGHT_PNG 8
-#define VNC_FEATURE_ZRLE 9
-#define VNC_FEATURE_ZYWRLE 10
-#define VNC_FEATURE_LED_STATE 11
-
-#define VNC_FEATURE_RESIZE_MASK (1 << VNC_FEATURE_RESIZE)
-#define VNC_FEATURE_HEXTILE_MASK (1 << VNC_FEATURE_HEXTILE)
-#define VNC_FEATURE_POINTER_TYPE_CHANGE_MASK (1 << VNC_FEATURE_POINTER_TYPE_CHANGE)
-#define VNC_FEATURE_WMVI_MASK (1 << VNC_FEATURE_WMVI)
-#define VNC_FEATURE_TIGHT_MASK (1 << VNC_FEATURE_TIGHT)
-#define VNC_FEATURE_ZLIB_MASK (1 << VNC_FEATURE_ZLIB)
-#define VNC_FEATURE_COPYRECT_MASK (1 << VNC_FEATURE_COPYRECT)
-#define VNC_FEATURE_RICH_CURSOR_MASK (1 << VNC_FEATURE_RICH_CURSOR)
-#define VNC_FEATURE_TIGHT_PNG_MASK (1 << VNC_FEATURE_TIGHT_PNG)
-#define VNC_FEATURE_ZRLE_MASK (1 << VNC_FEATURE_ZRLE)
-#define VNC_FEATURE_ZYWRLE_MASK (1 << VNC_FEATURE_ZYWRLE)
-#define VNC_FEATURE_LED_STATE_MASK (1 << VNC_FEATURE_LED_STATE)
-
-
-/* Client -> Server message IDs */
-#define VNC_MSG_CLIENT_SET_PIXEL_FORMAT 0
-#define VNC_MSG_CLIENT_SET_ENCODINGS 2
-#define VNC_MSG_CLIENT_FRAMEBUFFER_UPDATE_REQUEST 3
-#define VNC_MSG_CLIENT_KEY_EVENT 4
-#define VNC_MSG_CLIENT_POINTER_EVENT 5
-#define VNC_MSG_CLIENT_CUT_TEXT 6
-#define VNC_MSG_CLIENT_VMWARE_0 127
-#define VNC_MSG_CLIENT_CALL_CONTROL 249
-#define VNC_MSG_CLIENT_XVP 250
-#define VNC_MSG_CLIENT_SET_DESKTOP_SIZE 251
-#define VNC_MSG_CLIENT_TIGHT 252
-#define VNC_MSG_CLIENT_GII 253
-#define VNC_MSG_CLIENT_VMWARE_1 254
-#define VNC_MSG_CLIENT_QEMU 255
-
-/* Server -> Client message IDs */
-#define VNC_MSG_SERVER_FRAMEBUFFER_UPDATE 0
-#define VNC_MSG_SERVER_SET_COLOUR_MAP_ENTRIES 1
-#define VNC_MSG_SERVER_BELL 2
-#define VNC_MSG_SERVER_CUT_TEXT 3
-#define VNC_MSG_SERVER_VMWARE_0 127
-#define VNC_MSG_SERVER_CALL_CONTROL 249
-#define VNC_MSG_SERVER_XVP 250
-#define VNC_MSG_SERVER_TIGHT 252
-#define VNC_MSG_SERVER_GII 253
-#define VNC_MSG_SERVER_VMWARE_1 254
-#define VNC_MSG_SERVER_QEMU 255
-
-
-
-/* QEMU client -> server message IDs */
-#define VNC_MSG_CLIENT_QEMU_EXT_KEY_EVENT 0
-#define VNC_MSG_CLIENT_QEMU_AUDIO 1
-
-/* QEMU server -> client message IDs */
-#define VNC_MSG_SERVER_QEMU_AUDIO 1
-
-
-
-/* QEMU client -> server audio message IDs */
-#define VNC_MSG_CLIENT_QEMU_AUDIO_ENABLE 0
-#define VNC_MSG_CLIENT_QEMU_AUDIO_DISABLE 1
-#define VNC_MSG_CLIENT_QEMU_AUDIO_SET_FORMAT 2
-
-/* QEMU server -> client audio message IDs */
-#define VNC_MSG_SERVER_QEMU_AUDIO_END 0
-#define VNC_MSG_SERVER_QEMU_AUDIO_BEGIN 1
-#define VNC_MSG_SERVER_QEMU_AUDIO_DATA 2
-
-
-/*****************************************************************************
- *
- * Internal APIs
- *
- *****************************************************************************/
-
-/* Event loop functions */
-gboolean vnc_client_io(QIOChannel *ioc,
- GIOCondition condition,
- void *opaque);
-
-ssize_t vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen);
-ssize_t vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen);
-
-/* Protocol I/O functions */
-void vnc_write(VncState *vs, const void *data, size_t len);
-void vnc_write_u32(VncState *vs, uint32_t value);
-void vnc_write_s32(VncState *vs, int32_t value);
-void vnc_write_u16(VncState *vs, uint16_t value);
-void vnc_write_u8(VncState *vs, uint8_t value);
-void vnc_flush(VncState *vs);
-void vnc_read_when(VncState *vs, VncReadEvent *func, size_t expecting);
-void vnc_disconnect_finish(VncState *vs);
-void vnc_init_state(VncState *vs);
-
-
-/* Buffer I/O functions */
-uint32_t read_u32(uint8_t *data, size_t offset);
-
-/* Protocol stage functions */
-void vnc_client_error(VncState *vs);
-ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp);
-
-void start_client_init(VncState *vs);
-void start_auth_vnc(VncState *vs);
-
-
-/* Misc helpers */
-
-static inline uint32_t vnc_has_feature(VncState *vs, int feature) {
- return (vs->features & (1 << feature));
-}
-
-/* Framebuffer */
-void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
- int32_t encoding);
-
-/* server fb is in PIXMAN_x8r8g8b8 */
-#define VNC_SERVER_FB_FORMAT PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
-#define VNC_SERVER_FB_BITS (PIXMAN_FORMAT_BPP(VNC_SERVER_FB_FORMAT))
-#define VNC_SERVER_FB_BYTES ((VNC_SERVER_FB_BITS+7)/8)
-
-void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y);
-int vnc_server_fb_stride(VncDisplay *vd);
-
-void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v);
-double vnc_update_freq(VncState *vs, int x, int y, int w, int h);
-void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h);
-
-/* Encodings */
-int vnc_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
-
-int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
-
-int vnc_hextile_send_framebuffer_update(VncState *vs, int x,
- int y, int w, int h);
-void vnc_hextile_set_pixel_conversion(VncState *vs, int generic);
-
-void *vnc_zlib_zalloc(void *x, unsigned items, unsigned size);
-void vnc_zlib_zfree(void *x, void *addr);
-int vnc_zlib_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
-void vnc_zlib_clear(VncState *vs);
-
-int vnc_tight_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
-int vnc_tight_png_send_framebuffer_update(VncState *vs, int x, int y,
- int w, int h);
-void vnc_tight_clear(VncState *vs);
-
-int vnc_zrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
-int vnc_zywrle_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
-void vnc_zrle_clear(VncState *vs);
-
-#endif /* __QEMU_VNC_H */
diff --git a/qemu/ui/vnc_keysym.h b/qemu/ui/vnc_keysym.h
deleted file mode 100644
index 7fa2bc1f1..000000000
--- a/qemu/ui/vnc_keysym.h
+++ /dev/null
@@ -1,720 +0,0 @@
-
-#include "keymaps.h"
-
-static const name2keysym_t name2keysym[]={
-/* ascii */
- { "space", 0x020},
- { "exclam", 0x021},
- { "quotedbl", 0x022},
- { "numbersign", 0x023},
- { "dollar", 0x024},
- { "percent", 0x025},
- { "ampersand", 0x026},
- { "apostrophe", 0x027},
- { "parenleft", 0x028},
- { "parenright", 0x029},
- { "asterisk", 0x02a},
- { "plus", 0x02b},
- { "comma", 0x02c},
- { "minus", 0x02d},
- { "period", 0x02e},
- { "slash", 0x02f},
- { "0", 0x030},
- { "1", 0x031},
- { "2", 0x032},
- { "3", 0x033},
- { "4", 0x034},
- { "5", 0x035},
- { "6", 0x036},
- { "7", 0x037},
- { "8", 0x038},
- { "9", 0x039},
- { "colon", 0x03a},
- { "semicolon", 0x03b},
- { "less", 0x03c},
- { "equal", 0x03d},
- { "greater", 0x03e},
- { "question", 0x03f},
- { "at", 0x040},
- { "A", 0x041},
- { "B", 0x042},
- { "C", 0x043},
- { "D", 0x044},
- { "E", 0x045},
- { "F", 0x046},
- { "G", 0x047},
- { "H", 0x048},
- { "I", 0x049},
- { "J", 0x04a},
- { "K", 0x04b},
- { "L", 0x04c},
- { "M", 0x04d},
- { "N", 0x04e},
- { "O", 0x04f},
- { "P", 0x050},
- { "Q", 0x051},
- { "R", 0x052},
- { "S", 0x053},
- { "T", 0x054},
- { "U", 0x055},
- { "V", 0x056},
- { "W", 0x057},
- { "X", 0x058},
- { "Y", 0x059},
- { "Z", 0x05a},
- { "bracketleft", 0x05b},
- { "backslash", 0x05c},
- { "bracketright", 0x05d},
- { "asciicircum", 0x05e},
- { "underscore", 0x05f},
- { "grave", 0x060},
- { "a", 0x061},
- { "b", 0x062},
- { "c", 0x063},
- { "d", 0x064},
- { "e", 0x065},
- { "f", 0x066},
- { "g", 0x067},
- { "h", 0x068},
- { "i", 0x069},
- { "j", 0x06a},
- { "k", 0x06b},
- { "l", 0x06c},
- { "m", 0x06d},
- { "n", 0x06e},
- { "o", 0x06f},
- { "p", 0x070},
- { "q", 0x071},
- { "r", 0x072},
- { "s", 0x073},
- { "t", 0x074},
- { "u", 0x075},
- { "v", 0x076},
- { "w", 0x077},
- { "x", 0x078},
- { "y", 0x079},
- { "z", 0x07a},
- { "braceleft", 0x07b},
- { "bar", 0x07c},
- { "braceright", 0x07d},
- { "asciitilde", 0x07e},
-
-/* latin 1 extensions */
-{ "nobreakspace", 0x0a0},
-{ "exclamdown", 0x0a1},
-{ "cent", 0x0a2},
-{ "sterling", 0x0a3},
-{ "currency", 0x0a4},
-{ "yen", 0x0a5},
-{ "brokenbar", 0x0a6},
-{ "section", 0x0a7},
-{ "diaeresis", 0x0a8},
-{ "copyright", 0x0a9},
-{ "ordfeminine", 0x0aa},
-{ "guillemotleft", 0x0ab},
-{ "notsign", 0x0ac},
-{ "hyphen", 0x0ad},
-{ "registered", 0x0ae},
-{ "macron", 0x0af},
-{ "degree", 0x0b0},
-{ "plusminus", 0x0b1},
-{ "twosuperior", 0x0b2},
-{ "threesuperior", 0x0b3},
-{ "acute", 0x0b4},
-{ "mu", 0x0b5},
-{ "paragraph", 0x0b6},
-{ "periodcentered", 0x0b7},
-{ "cedilla", 0x0b8},
-{ "onesuperior", 0x0b9},
-{ "masculine", 0x0ba},
-{ "guillemotright", 0x0bb},
-{ "onequarter", 0x0bc},
-{ "onehalf", 0x0bd},
-{ "threequarters", 0x0be},
-{ "questiondown", 0x0bf},
-{ "Agrave", 0x0c0},
-{ "Aacute", 0x0c1},
-{ "Acircumflex", 0x0c2},
-{ "Atilde", 0x0c3},
-{ "Adiaeresis", 0x0c4},
-{ "Aring", 0x0c5},
-{ "AE", 0x0c6},
-{ "Ccedilla", 0x0c7},
-{ "Egrave", 0x0c8},
-{ "Eacute", 0x0c9},
-{ "Ecircumflex", 0x0ca},
-{ "Ediaeresis", 0x0cb},
-{ "Igrave", 0x0cc},
-{ "Iacute", 0x0cd},
-{ "Icircumflex", 0x0ce},
-{ "Idiaeresis", 0x0cf},
-{ "ETH", 0x0d0},
-{ "Eth", 0x0d0},
-{ "Ntilde", 0x0d1},
-{ "Ograve", 0x0d2},
-{ "Oacute", 0x0d3},
-{ "Ocircumflex", 0x0d4},
-{ "Otilde", 0x0d5},
-{ "Odiaeresis", 0x0d6},
-{ "multiply", 0x0d7},
-{ "Ooblique", 0x0d8},
-{ "Oslash", 0x0d8},
-{ "Ugrave", 0x0d9},
-{ "Uacute", 0x0da},
-{ "Ucircumflex", 0x0db},
-{ "Udiaeresis", 0x0dc},
-{ "Yacute", 0x0dd},
-{ "THORN", 0x0de},
-{ "Thorn", 0x0de},
-{ "ssharp", 0x0df},
-{ "agrave", 0x0e0},
-{ "aacute", 0x0e1},
-{ "acircumflex", 0x0e2},
-{ "atilde", 0x0e3},
-{ "adiaeresis", 0x0e4},
-{ "aring", 0x0e5},
-{ "ae", 0x0e6},
-{ "ccedilla", 0x0e7},
-{ "egrave", 0x0e8},
-{ "eacute", 0x0e9},
-{ "ecircumflex", 0x0ea},
-{ "ediaeresis", 0x0eb},
-{ "igrave", 0x0ec},
-{ "iacute", 0x0ed},
-{ "icircumflex", 0x0ee},
-{ "idiaeresis", 0x0ef},
-{ "eth", 0x0f0},
-{ "ntilde", 0x0f1},
-{ "ograve", 0x0f2},
-{ "oacute", 0x0f3},
-{ "ocircumflex", 0x0f4},
-{ "otilde", 0x0f5},
-{ "odiaeresis", 0x0f6},
-{ "division", 0x0f7},
-{ "oslash", 0x0f8},
-{ "ooblique", 0x0f8},
-{ "ugrave", 0x0f9},
-{ "uacute", 0x0fa},
-{ "ucircumflex", 0x0fb},
-{ "udiaeresis", 0x0fc},
-{ "yacute", 0x0fd},
-{ "thorn", 0x0fe},
-{ "ydiaeresis", 0x0ff},
-{"EuroSign", 0x20ac}, /* XK_EuroSign */
-
-/* latin 2 - Polish national characters */
-{ "eogonek", 0x1ea},
-{ "Eogonek", 0x1ca},
-{ "aogonek", 0x1b1},
-{ "Aogonek", 0x1a1},
-{ "sacute", 0x1b6},
-{ "Sacute", 0x1a6},
-{ "lstroke", 0x1b3},
-{ "Lstroke", 0x1a3},
-{ "zabovedot", 0x1bf},
-{ "Zabovedot", 0x1af},
-{ "zacute", 0x1bc},
-{ "Zacute", 0x1ac},
-{ "Odoubleacute", 0x1d5},
-{ "Udoubleacute", 0x1db},
-{ "cacute", 0x1e6},
-{ "Cacute", 0x1c6},
-{ "nacute", 0x1f1},
-{ "Nacute", 0x1d1},
-{ "odoubleacute", 0x1f5},
-{ "udoubleacute", 0x1fb},
-
-/* Czech national characters */
-{ "ecaron", 0x1ec},
-{ "scaron", 0x1b9},
-{ "ccaron", 0x1e8},
-{ "rcaron", 0x1f8},
-{ "zcaron", 0x1be},
-{ "uring", 0x1f9},
-
- /* modifiers */
-{"ISO_Level3_Shift", 0xfe03}, /* XK_ISO_Level3_Shift */
-{"Control_L", 0xffe3}, /* XK_Control_L */
-{"Control_R", 0xffe4}, /* XK_Control_R */
-{"Alt_L", 0xffe9}, /* XK_Alt_L */
-{"Alt_R", 0xffea}, /* XK_Alt_R */
-{"Caps_Lock", 0xffe5}, /* XK_Caps_Lock */
-{"Meta_L", 0xffe7}, /* XK_Meta_L */
-{"Meta_R", 0xffe8}, /* XK_Meta_R */
-{"Shift_L", 0xffe1}, /* XK_Shift_L */
-{"Shift_R", 0xffe2}, /* XK_Shift_R */
-{"Super_L", 0xffeb}, /* XK_Super_L */
-{"Super_R", 0xffec}, /* XK_Super_R */
-
- /* special keys */
-{"BackSpace", 0xff08}, /* XK_BackSpace */
-{"Tab", 0xff09}, /* XK_Tab */
-{"Return", 0xff0d}, /* XK_Return */
-{"Right", 0xff53}, /* XK_Right */
-{"Left", 0xff51}, /* XK_Left */
-{"Up", 0xff52}, /* XK_Up */
-{"Down", 0xff54}, /* XK_Down */
-{"Page_Down", 0xff56}, /* XK_Page_Down */
-{"Page_Up", 0xff55}, /* XK_Page_Up */
-{"Insert", 0xff63}, /* XK_Insert */
-{"Delete", 0xffff}, /* XK_Delete */
-{"Home", 0xff50}, /* XK_Home */
-{"End", 0xff57}, /* XK_End */
-{"Scroll_Lock", 0xff14}, /* XK_Scroll_Lock */
-{"KP_Home", 0xff95},
-{"KP_Left", 0xff96},
-{"KP_Up", 0xff97},
-{"KP_Right", 0xff98},
-{"KP_Down", 0xff99},
-{"KP_Prior", 0xff9a},
-{"KP_Page_Up", 0xff9a},
-{"KP_Next", 0xff9b},
-{"KP_Page_Down", 0xff9b},
-{"KP_End", 0xff9c},
-{"KP_Begin", 0xff9d},
-{"KP_Insert", 0xff9e},
-{"KP_Delete", 0xff9f},
-{"F1", 0xffbe}, /* XK_F1 */
-{"F2", 0xffbf}, /* XK_F2 */
-{"F3", 0xffc0}, /* XK_F3 */
-{"F4", 0xffc1}, /* XK_F4 */
-{"F5", 0xffc2}, /* XK_F5 */
-{"F6", 0xffc3}, /* XK_F6 */
-{"F7", 0xffc4}, /* XK_F7 */
-{"F8", 0xffc5}, /* XK_F8 */
-{"F9", 0xffc6}, /* XK_F9 */
-{"F10", 0xffc7}, /* XK_F10 */
-{"F11", 0xffc8}, /* XK_F11 */
-{"F12", 0xffc9}, /* XK_F12 */
-{"F13", 0xffca}, /* XK_F13 */
-{"F14", 0xffcb}, /* XK_F14 */
-{"F15", 0xffcc}, /* XK_F15 */
-{"Sys_Req", 0xff15}, /* XK_Sys_Req */
-{"KP_0", 0xffb0}, /* XK_KP_0 */
-{"KP_1", 0xffb1}, /* XK_KP_1 */
-{"KP_2", 0xffb2}, /* XK_KP_2 */
-{"KP_3", 0xffb3}, /* XK_KP_3 */
-{"KP_4", 0xffb4}, /* XK_KP_4 */
-{"KP_5", 0xffb5}, /* XK_KP_5 */
-{"KP_6", 0xffb6}, /* XK_KP_6 */
-{"KP_7", 0xffb7}, /* XK_KP_7 */
-{"KP_8", 0xffb8}, /* XK_KP_8 */
-{"KP_9", 0xffb9}, /* XK_KP_9 */
-{"KP_Add", 0xffab}, /* XK_KP_Add */
-{"KP_Separator", 0xffac},/* XK_KP_Separator */
-{"KP_Decimal", 0xffae}, /* XK_KP_Decimal */
-{"KP_Divide", 0xffaf}, /* XK_KP_Divide */
-{"KP_Enter", 0xff8d}, /* XK_KP_Enter */
-{"KP_Equal", 0xffbd}, /* XK_KP_Equal */
-{"KP_Multiply", 0xffaa}, /* XK_KP_Multiply */
-{"KP_Subtract", 0xffad}, /* XK_KP_Subtract */
-{"help", 0xff6a}, /* XK_Help */
-{"Menu", 0xff67}, /* XK_Menu */
-{"Print", 0xff61}, /* XK_Print */
-{"Mode_switch", 0xff7e}, /* XK_Mode_switch */
-{"Num_Lock", 0xff7f}, /* XK_Num_Lock */
-{"Pause", 0xff13}, /* XK_Pause */
-{"Escape", 0xff1b}, /* XK_Escape */
-
-/* dead keys */
-{"dead_grave", 0xfe50}, /* XK_dead_grave */
-{"dead_acute", 0xfe51}, /* XK_dead_acute */
-{"dead_circumflex", 0xfe52}, /* XK_dead_circumflex */
-{"dead_tilde", 0xfe53}, /* XK_dead_tilde */
-{"dead_macron", 0xfe54}, /* XK_dead_macron */
-{"dead_breve", 0xfe55}, /* XK_dead_breve */
-{"dead_abovedot", 0xfe56}, /* XK_dead_abovedot */
-{"dead_diaeresis", 0xfe57}, /* XK_dead_diaeresis */
-{"dead_abovering", 0xfe58}, /* XK_dead_abovering */
-{"dead_doubleacute", 0xfe59}, /* XK_dead_doubleacute */
-{"dead_caron", 0xfe5a}, /* XK_dead_caron */
-{"dead_cedilla", 0xfe5b}, /* XK_dead_cedilla */
-{"dead_ogonek", 0xfe5c}, /* XK_dead_ogonek */
-{"dead_iota", 0xfe5d}, /* XK_dead_iota */
-{"dead_voiced_sound", 0xfe5e}, /* XK_dead_voiced_sound */
-{"dead_semivoiced_sound", 0xfe5f}, /* XK_dead_semivoiced_sound */
-{"dead_belowdot", 0xfe60}, /* XK_dead_belowdot */
-{"dead_hook", 0xfe61}, /* XK_dead_hook */
-{"dead_horn", 0xfe62}, /* XK_dead_horn */
-
-
- /* localized keys */
-{"BackApostrophe", 0xff21},
-{"Muhenkan", 0xff22},
-{"Katakana", 0xff27},
-{"Hankaku", 0xff29},
-{"Zenkaku_Hankaku", 0xff2a},
-{"Henkan_Mode_Real", 0xff23},
-{"Henkan_Mode_Ultra", 0xff3e},
-{"backslash_ja", 0xffa5},
-{"Katakana_Real", 0xff25},
-{"Eisu_toggle", 0xff30},
-
-{"abovedot", 0x01ff}, /* U+02D9 DOT ABOVE */
-{"amacron", 0x03e0}, /* U+0101 LATIN SMALL LETTER A WITH MACRON */
-{"Amacron", 0x03c0}, /* U+0100 LATIN CAPITAL LETTER A WITH MACRON */
-{"Arabic_ain", 0x05d9}, /* U+0639 ARABIC LETTER AIN */
-{"Arabic_alef", 0x05c7}, /* U+0627 ARABIC LETTER ALEF */
-{"Arabic_alefmaksura", 0x05e9}, /* U+0649 ARABIC LETTER ALEF MAKSURA */
-{"Arabic_beh", 0x05c8}, /* U+0628 ARABIC LETTER BEH */
-{"Arabic_comma", 0x05ac}, /* U+060C ARABIC COMMA */
-{"Arabic_dad", 0x05d6}, /* U+0636 ARABIC LETTER DAD */
-{"Arabic_dal", 0x05cf}, /* U+062F ARABIC LETTER DAL */
-{"Arabic_damma", 0x05ef}, /* U+064F ARABIC DAMMA */
-{"Arabic_dammatan", 0x05ec}, /* U+064C ARABIC DAMMATAN */
-{"Arabic_fatha", 0x05ee}, /* U+064E ARABIC FATHA */
-{"Arabic_fathatan", 0x05eb}, /* U+064B ARABIC FATHATAN */
-{"Arabic_feh", 0x05e1}, /* U+0641 ARABIC LETTER FEH */
-{"Arabic_ghain", 0x05da}, /* U+063A ARABIC LETTER GHAIN */
-{"Arabic_ha", 0x05e7}, /* U+0647 ARABIC LETTER HEH */
-{"Arabic_hah", 0x05cd}, /* U+062D ARABIC LETTER HAH */
-{"Arabic_hamza", 0x05c1}, /* U+0621 ARABIC LETTER HAMZA */
-{"Arabic_hamzaonalef", 0x05c3}, /* U+0623 ARABIC LETTER ALEF WITH HAMZA ABOVE */
-{"Arabic_hamzaonwaw", 0x05c4}, /* U+0624 ARABIC LETTER WAW WITH HAMZA ABOVE */
-{"Arabic_hamzaonyeh", 0x05c6}, /* U+0626 ARABIC LETTER YEH WITH HAMZA ABOVE */
-{"Arabic_hamzaunderalef", 0x05c5}, /* U+0625 ARABIC LETTER ALEF WITH HAMZA BELOW */
-{"Arabic_jeem", 0x05cc}, /* U+062C ARABIC LETTER JEEM */
-{"Arabic_kaf", 0x05e3}, /* U+0643 ARABIC LETTER KAF */
-{"Arabic_kasra", 0x05f0}, /* U+0650 ARABIC KASRA */
-{"Arabic_kasratan", 0x05ed}, /* U+064D ARABIC KASRATAN */
-{"Arabic_khah", 0x05ce}, /* U+062E ARABIC LETTER KHAH */
-{"Arabic_lam", 0x05e4}, /* U+0644 ARABIC LETTER LAM */
-{"Arabic_maddaonalef", 0x05c2}, /* U+0622 ARABIC LETTER ALEF WITH MADDA ABOVE */
-{"Arabic_meem", 0x05e5}, /* U+0645 ARABIC LETTER MEEM */
-{"Arabic_noon", 0x05e6}, /* U+0646 ARABIC LETTER NOON */
-{"Arabic_qaf", 0x05e2}, /* U+0642 ARABIC LETTER QAF */
-{"Arabic_question_mark", 0x05bf}, /* U+061F ARABIC QUESTION MARK */
-{"Arabic_ra", 0x05d1}, /* U+0631 ARABIC LETTER REH */
-{"Arabic_sad", 0x05d5}, /* U+0635 ARABIC LETTER SAD */
-{"Arabic_seen", 0x05d3}, /* U+0633 ARABIC LETTER SEEN */
-{"Arabic_semicolon", 0x05bb}, /* U+061B ARABIC SEMICOLON */
-{"Arabic_shadda", 0x05f1}, /* U+0651 ARABIC SHADDA */
-{"Arabic_sheen", 0x05d4}, /* U+0634 ARABIC LETTER SHEEN */
-{"Arabic_sukun", 0x05f2}, /* U+0652 ARABIC SUKUN */
-{"Arabic_tah", 0x05d7}, /* U+0637 ARABIC LETTER TAH */
-{"Arabic_tatweel", 0x05e0}, /* U+0640 ARABIC TATWEEL */
-{"Arabic_teh", 0x05ca}, /* U+062A ARABIC LETTER TEH */
-{"Arabic_tehmarbuta", 0x05c9}, /* U+0629 ARABIC LETTER TEH MARBUTA */
-{"Arabic_thal", 0x05d0}, /* U+0630 ARABIC LETTER THAL */
-{"Arabic_theh", 0x05cb}, /* U+062B ARABIC LETTER THEH */
-{"Arabic_waw", 0x05e8}, /* U+0648 ARABIC LETTER WAW */
-{"Arabic_yeh", 0x05ea}, /* U+064A ARABIC LETTER YEH */
-{"Arabic_zah", 0x05d8}, /* U+0638 ARABIC LETTER ZAH */
-{"Arabic_zain", 0x05d2}, /* U+0632 ARABIC LETTER ZAIN */
-{"breve", 0x01a2}, /* U+02D8 BREVE */
-{"caron", 0x01b7}, /* U+02C7 CARON */
-{"Ccaron", 0x01c8}, /* U+010C LATIN CAPITAL LETTER C WITH CARON */
-{"numerosign", 0x06b0}, /* U+2116 NUMERO SIGN */
-{"Cyrillic_a", 0x06c1}, /* U+0430 CYRILLIC SMALL LETTER A */
-{"Cyrillic_A", 0x06e1}, /* U+0410 CYRILLIC CAPITAL LETTER A */
-{"Cyrillic_be", 0x06c2}, /* U+0431 CYRILLIC SMALL LETTER BE */
-{"Cyrillic_BE", 0x06e2}, /* U+0411 CYRILLIC CAPITAL LETTER BE */
-{"Cyrillic_che", 0x06de}, /* U+0447 CYRILLIC SMALL LETTER CHE */
-{"Cyrillic_CHE", 0x06fe}, /* U+0427 CYRILLIC CAPITAL LETTER CHE */
-{"Cyrillic_de", 0x06c4}, /* U+0434 CYRILLIC SMALL LETTER DE */
-{"Cyrillic_DE", 0x06e4}, /* U+0414 CYRILLIC CAPITAL LETTER DE */
-{"Cyrillic_dzhe", 0x06af}, /* U+045F CYRILLIC SMALL LETTER DZHE */
-{"Cyrillic_DZHE", 0x06bf}, /* U+040F CYRILLIC CAPITAL LETTER DZHE */
-{"Cyrillic_e", 0x06dc}, /* U+044D CYRILLIC SMALL LETTER E */
-{"Cyrillic_E", 0x06fc}, /* U+042D CYRILLIC CAPITAL LETTER E */
-{"Cyrillic_ef", 0x06c6}, /* U+0444 CYRILLIC SMALL LETTER EF */
-{"Cyrillic_EF", 0x06e6}, /* U+0424 CYRILLIC CAPITAL LETTER EF */
-{"Cyrillic_el", 0x06cc}, /* U+043B CYRILLIC SMALL LETTER EL */
-{"Cyrillic_EL", 0x06ec}, /* U+041B CYRILLIC CAPITAL LETTER EL */
-{"Cyrillic_em", 0x06cd}, /* U+043C CYRILLIC SMALL LETTER EM */
-{"Cyrillic_EM", 0x06ed}, /* U+041C CYRILLIC CAPITAL LETTER EM */
-{"Cyrillic_en", 0x06ce}, /* U+043D CYRILLIC SMALL LETTER EN */
-{"Cyrillic_EN", 0x06ee}, /* U+041D CYRILLIC CAPITAL LETTER EN */
-{"Cyrillic_er", 0x06d2}, /* U+0440 CYRILLIC SMALL LETTER ER */
-{"Cyrillic_ER", 0x06f2}, /* U+0420 CYRILLIC CAPITAL LETTER ER */
-{"Cyrillic_es", 0x06d3}, /* U+0441 CYRILLIC SMALL LETTER ES */
-{"Cyrillic_ES", 0x06f3}, /* U+0421 CYRILLIC CAPITAL LETTER ES */
-{"Cyrillic_ghe", 0x06c7}, /* U+0433 CYRILLIC SMALL LETTER GHE */
-{"Cyrillic_GHE", 0x06e7}, /* U+0413 CYRILLIC CAPITAL LETTER GHE */
-{"Cyrillic_ha", 0x06c8}, /* U+0445 CYRILLIC SMALL LETTER HA */
-{"Cyrillic_HA", 0x06e8}, /* U+0425 CYRILLIC CAPITAL LETTER HA */
-{"Cyrillic_hardsign", 0x06df}, /* U+044A CYRILLIC SMALL LETTER HARD SIGN */
-{"Cyrillic_HARDSIGN", 0x06ff}, /* U+042A CYRILLIC CAPITAL LETTER HARD SIGN */
-{"Cyrillic_i", 0x06c9}, /* U+0438 CYRILLIC SMALL LETTER I */
-{"Cyrillic_I", 0x06e9}, /* U+0418 CYRILLIC CAPITAL LETTER I */
-{"Cyrillic_ie", 0x06c5}, /* U+0435 CYRILLIC SMALL LETTER IE */
-{"Cyrillic_IE", 0x06e5}, /* U+0415 CYRILLIC CAPITAL LETTER IE */
-{"Cyrillic_io", 0x06a3}, /* U+0451 CYRILLIC SMALL LETTER IO */
-{"Cyrillic_IO", 0x06b3}, /* U+0401 CYRILLIC CAPITAL LETTER IO */
-{"Cyrillic_je", 0x06a8}, /* U+0458 CYRILLIC SMALL LETTER JE */
-{"Cyrillic_JE", 0x06b8}, /* U+0408 CYRILLIC CAPITAL LETTER JE */
-{"Cyrillic_ka", 0x06cb}, /* U+043A CYRILLIC SMALL LETTER KA */
-{"Cyrillic_KA", 0x06eb}, /* U+041A CYRILLIC CAPITAL LETTER KA */
-{"Cyrillic_lje", 0x06a9}, /* U+0459 CYRILLIC SMALL LETTER LJE */
-{"Cyrillic_LJE", 0x06b9}, /* U+0409 CYRILLIC CAPITAL LETTER LJE */
-{"Cyrillic_nje", 0x06aa}, /* U+045A CYRILLIC SMALL LETTER NJE */
-{"Cyrillic_NJE", 0x06ba}, /* U+040A CYRILLIC CAPITAL LETTER NJE */
-{"Cyrillic_o", 0x06cf}, /* U+043E CYRILLIC SMALL LETTER O */
-{"Cyrillic_O", 0x06ef}, /* U+041E CYRILLIC CAPITAL LETTER O */
-{"Cyrillic_pe", 0x06d0}, /* U+043F CYRILLIC SMALL LETTER PE */
-{"Cyrillic_PE", 0x06f0}, /* U+041F CYRILLIC CAPITAL LETTER PE */
-{"Cyrillic_sha", 0x06db}, /* U+0448 CYRILLIC SMALL LETTER SHA */
-{"Cyrillic_SHA", 0x06fb}, /* U+0428 CYRILLIC CAPITAL LETTER SHA */
-{"Cyrillic_shcha", 0x06dd}, /* U+0449 CYRILLIC SMALL LETTER SHCHA */
-{"Cyrillic_SHCHA", 0x06fd}, /* U+0429 CYRILLIC CAPITAL LETTER SHCHA */
-{"Cyrillic_shorti", 0x06ca}, /* U+0439 CYRILLIC SMALL LETTER SHORT I */
-{"Cyrillic_SHORTI", 0x06ea}, /* U+0419 CYRILLIC CAPITAL LETTER SHORT I */
-{"Cyrillic_softsign", 0x06d8}, /* U+044C CYRILLIC SMALL LETTER SOFT SIGN */
-{"Cyrillic_SOFTSIGN", 0x06f8}, /* U+042C CYRILLIC CAPITAL LETTER SOFT SIGN */
-{"Cyrillic_te", 0x06d4}, /* U+0442 CYRILLIC SMALL LETTER TE */
-{"Cyrillic_TE", 0x06f4}, /* U+0422 CYRILLIC CAPITAL LETTER TE */
-{"Cyrillic_tse", 0x06c3}, /* U+0446 CYRILLIC SMALL LETTER TSE */
-{"Cyrillic_TSE", 0x06e3}, /* U+0426 CYRILLIC CAPITAL LETTER TSE */
-{"Cyrillic_u", 0x06d5}, /* U+0443 CYRILLIC SMALL LETTER U */
-{"Cyrillic_U", 0x06f5}, /* U+0423 CYRILLIC CAPITAL LETTER U */
-{"Cyrillic_ve", 0x06d7}, /* U+0432 CYRILLIC SMALL LETTER VE */
-{"Cyrillic_VE", 0x06f7}, /* U+0412 CYRILLIC CAPITAL LETTER VE */
-{"Cyrillic_ya", 0x06d1}, /* U+044F CYRILLIC SMALL LETTER YA */
-{"Cyrillic_YA", 0x06f1}, /* U+042F CYRILLIC CAPITAL LETTER YA */
-{"Cyrillic_yeru", 0x06d9}, /* U+044B CYRILLIC SMALL LETTER YERU */
-{"Cyrillic_YERU", 0x06f9}, /* U+042B CYRILLIC CAPITAL LETTER YERU */
-{"Cyrillic_yu", 0x06c0}, /* U+044E CYRILLIC SMALL LETTER YU */
-{"Cyrillic_YU", 0x06e0}, /* U+042E CYRILLIC CAPITAL LETTER YU */
-{"Cyrillic_ze", 0x06da}, /* U+0437 CYRILLIC SMALL LETTER ZE */
-{"Cyrillic_ZE", 0x06fa}, /* U+0417 CYRILLIC CAPITAL LETTER ZE */
-{"Cyrillic_zhe", 0x06d6}, /* U+0436 CYRILLIC SMALL LETTER ZHE */
-{"Cyrillic_ZHE", 0x06f6}, /* U+0416 CYRILLIC CAPITAL LETTER ZHE */
-{"doubleacute", 0x01bd}, /* U+02DD DOUBLE ACUTE ACCENT */
-{"doublelowquotemark", 0x0afe}, /* U+201E DOUBLE LOW-9 QUOTATION MARK */
-{"downarrow", 0x08fe}, /* U+2193 DOWNWARDS ARROW */
-{"dstroke", 0x01f0}, /* U+0111 LATIN SMALL LETTER D WITH STROKE */
-{"Dstroke", 0x01d0}, /* U+0110 LATIN CAPITAL LETTER D WITH STROKE */
-{"eabovedot", 0x03ec}, /* U+0117 LATIN SMALL LETTER E WITH DOT ABOVE */
-{"Eabovedot", 0x03cc}, /* U+0116 LATIN CAPITAL LETTER E WITH DOT ABOVE */
-{"emacron", 0x03ba}, /* U+0113 LATIN SMALL LETTER E WITH MACRON */
-{"Emacron", 0x03aa}, /* U+0112 LATIN CAPITAL LETTER E WITH MACRON */
-{"endash", 0x0aaa}, /* U+2013 EN DASH */
-{"eng", 0x03bf}, /* U+014B LATIN SMALL LETTER ENG */
-{"ENG", 0x03bd}, /* U+014A LATIN CAPITAL LETTER ENG */
-{"Execute", 0xff62}, /* Execute, run, do */
-{"F16", 0xffcd},
-{"F17", 0xffce},
-{"F18", 0xffcf},
-{"F19", 0xffd0},
-{"F20", 0xffd1},
-{"F21", 0xffd2},
-{"F22", 0xffd3},
-{"F23", 0xffd4},
-{"F24", 0xffd5},
-{"F25", 0xffd6},
-{"F26", 0xffd7},
-{"F27", 0xffd8},
-{"F28", 0xffd9},
-{"F29", 0xffda},
-{"F30", 0xffdb},
-{"F31", 0xffdc},
-{"F32", 0xffdd},
-{"F33", 0xffde},
-{"F34", 0xffdf},
-{"F35", 0xffe0},
-{"fiveeighths", 0x0ac5}, /* U+215D VULGAR FRACTION FIVE EIGHTHS */
-{"gbreve", 0x02bb}, /* U+011F LATIN SMALL LETTER G WITH BREVE */
-{"Gbreve", 0x02ab}, /* U+011E LATIN CAPITAL LETTER G WITH BREVE */
-{"gcedilla", 0x03bb}, /* U+0123 LATIN SMALL LETTER G WITH CEDILLA */
-{"Gcedilla", 0x03ab}, /* U+0122 LATIN CAPITAL LETTER G WITH CEDILLA */
-{"Greek_OMEGA", 0x07d9}, /* U+03A9 GREEK CAPITAL LETTER OMEGA */
-{"Henkan_Mode", 0xff23}, /* Start/Stop Conversion */
-{"horizconnector", 0x08a3}, /*(U+2500 BOX DRAWINGS LIGHT HORIZONTAL)*/
-{"hstroke", 0x02b1}, /* U+0127 LATIN SMALL LETTER H WITH STROKE */
-{"Hstroke", 0x02a1}, /* U+0126 LATIN CAPITAL LETTER H WITH STROKE */
-{"Iabovedot", 0x02a9}, /* U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE */
-{"idotless", 0x02b9}, /* U+0131 LATIN SMALL LETTER DOTLESS I */
-{"imacron", 0x03ef}, /* U+012B LATIN SMALL LETTER I WITH MACRON */
-{"Imacron", 0x03cf}, /* U+012A LATIN CAPITAL LETTER I WITH MACRON */
-{"iogonek", 0x03e7}, /* U+012F LATIN SMALL LETTER I WITH OGONEK */
-{"Iogonek", 0x03c7}, /* U+012E LATIN CAPITAL LETTER I WITH OGONEK */
-{"ISO_First_Group", 0xfe0c},
-{"ISO_Last_Group", 0xfe0e},
-{"ISO_Next_Group", 0xfe08},
-{"kana_a", 0x04a7}, /* U+30A1 KATAKANA LETTER SMALL A */
-{"kana_A", 0x04b1}, /* U+30A2 KATAKANA LETTER A */
-{"kana_CHI", 0x04c1}, /* U+30C1 KATAKANA LETTER TI */
-{"kana_closingbracket", 0x04a3}, /* U+300D RIGHT CORNER BRACKET */
-{"kana_comma", 0x04a4}, /* U+3001 IDEOGRAPHIC COMMA */
-{"kana_conjunctive", 0x04a5}, /* U+30FB KATAKANA MIDDLE DOT */
-{"kana_e", 0x04aa}, /* U+30A7 KATAKANA LETTER SMALL E */
-{"kana_E", 0x04b4}, /* U+30A8 KATAKANA LETTER E */
-{"kana_FU", 0x04cc}, /* U+30D5 KATAKANA LETTER HU */
-{"kana_fullstop", 0x04a1}, /* U+3002 IDEOGRAPHIC FULL STOP */
-{"kana_HA", 0x04ca}, /* U+30CF KATAKANA LETTER HA */
-{"kana_HE", 0x04cd}, /* U+30D8 KATAKANA LETTER HE */
-{"kana_HI", 0x04cb}, /* U+30D2 KATAKANA LETTER HI */
-{"kana_HO", 0x04ce}, /* U+30DB KATAKANA LETTER HO */
-{"kana_i", 0x04a8}, /* U+30A3 KATAKANA LETTER SMALL I */
-{"kana_I", 0x04b2}, /* U+30A4 KATAKANA LETTER I */
-{"kana_KA", 0x04b6}, /* U+30AB KATAKANA LETTER KA */
-{"kana_KE", 0x04b9}, /* U+30B1 KATAKANA LETTER KE */
-{"kana_KI", 0x04b7}, /* U+30AD KATAKANA LETTER KI */
-{"kana_KO", 0x04ba}, /* U+30B3 KATAKANA LETTER KO */
-{"kana_KU", 0x04b8}, /* U+30AF KATAKANA LETTER KU */
-{"kana_MA", 0x04cf}, /* U+30DE KATAKANA LETTER MA */
-{"kana_ME", 0x04d2}, /* U+30E1 KATAKANA LETTER ME */
-{"kana_MI", 0x04d0}, /* U+30DF KATAKANA LETTER MI */
-{"kana_MO", 0x04d3}, /* U+30E2 KATAKANA LETTER MO */
-{"kana_MU", 0x04d1}, /* U+30E0 KATAKANA LETTER MU */
-{"kana_N", 0x04dd}, /* U+30F3 KATAKANA LETTER N */
-{"kana_NA", 0x04c5}, /* U+30CA KATAKANA LETTER NA */
-{"kana_NE", 0x04c8}, /* U+30CD KATAKANA LETTER NE */
-{"kana_NI", 0x04c6}, /* U+30CB KATAKANA LETTER NI */
-{"kana_NO", 0x04c9}, /* U+30CE KATAKANA LETTER NO */
-{"kana_NU", 0x04c7}, /* U+30CC KATAKANA LETTER NU */
-{"kana_o", 0x04ab}, /* U+30A9 KATAKANA LETTER SMALL O */
-{"kana_O", 0x04b5}, /* U+30AA KATAKANA LETTER O */
-{"kana_openingbracket", 0x04a2}, /* U+300C LEFT CORNER BRACKET */
-{"kana_RA", 0x04d7}, /* U+30E9 KATAKANA LETTER RA */
-{"kana_RE", 0x04da}, /* U+30EC KATAKANA LETTER RE */
-{"kana_RI", 0x04d8}, /* U+30EA KATAKANA LETTER RI */
-{"kana_RU", 0x04d9}, /* U+30EB KATAKANA LETTER RU */
-{"kana_SA", 0x04bb}, /* U+30B5 KATAKANA LETTER SA */
-{"kana_SE", 0x04be}, /* U+30BB KATAKANA LETTER SE */
-{"kana_SHI", 0x04bc}, /* U+30B7 KATAKANA LETTER SI */
-{"kana_SO", 0x04bf}, /* U+30BD KATAKANA LETTER SO */
-{"kana_SU", 0x04bd}, /* U+30B9 KATAKANA LETTER SU */
-{"kana_TA", 0x04c0}, /* U+30BF KATAKANA LETTER TA */
-{"kana_TE", 0x04c3}, /* U+30C6 KATAKANA LETTER TE */
-{"kana_TO", 0x04c4}, /* U+30C8 KATAKANA LETTER TO */
-{"kana_tsu", 0x04af}, /* U+30C3 KATAKANA LETTER SMALL TU */
-{"kana_TSU", 0x04c2}, /* U+30C4 KATAKANA LETTER TU */
-{"kana_u", 0x04a9}, /* U+30A5 KATAKANA LETTER SMALL U */
-{"kana_U", 0x04b3}, /* U+30A6 KATAKANA LETTER U */
-{"kana_WA", 0x04dc}, /* U+30EF KATAKANA LETTER WA */
-{"kana_WO", 0x04a6}, /* U+30F2 KATAKANA LETTER WO */
-{"kana_ya", 0x04ac}, /* U+30E3 KATAKANA LETTER SMALL YA */
-{"kana_YA", 0x04d4}, /* U+30E4 KATAKANA LETTER YA */
-{"kana_yo", 0x04ae}, /* U+30E7 KATAKANA LETTER SMALL YO */
-{"kana_YO", 0x04d6}, /* U+30E8 KATAKANA LETTER YO */
-{"kana_yu", 0x04ad}, /* U+30E5 KATAKANA LETTER SMALL YU */
-{"kana_YU", 0x04d5}, /* U+30E6 KATAKANA LETTER YU */
-{"Kanji", 0xff21}, /* Kanji, Kanji convert */
-{"kcedilla", 0x03f3}, /* U+0137 LATIN SMALL LETTER K WITH CEDILLA */
-{"Kcedilla", 0x03d3}, /* U+0136 LATIN CAPITAL LETTER K WITH CEDILLA */
-{"kra", 0x03a2}, /* U+0138 LATIN SMALL LETTER KRA */
-{"lcedilla", 0x03b6}, /* U+013C LATIN SMALL LETTER L WITH CEDILLA */
-{"Lcedilla", 0x03a6}, /* U+013B LATIN CAPITAL LETTER L WITH CEDILLA */
-{"leftarrow", 0x08fb}, /* U+2190 LEFTWARDS ARROW */
-{"leftdoublequotemark", 0x0ad2}, /* U+201C LEFT DOUBLE QUOTATION MARK */
-{"Macedonia_dse", 0x06a5}, /* U+0455 CYRILLIC SMALL LETTER DZE */
-{"Macedonia_DSE", 0x06b5}, /* U+0405 CYRILLIC CAPITAL LETTER DZE */
-{"Macedonia_gje", 0x06a2}, /* U+0453 CYRILLIC SMALL LETTER GJE */
-{"Macedonia_GJE", 0x06b2}, /* U+0403 CYRILLIC CAPITAL LETTER GJE */
-{"Macedonia_kje", 0x06ac}, /* U+045C CYRILLIC SMALL LETTER KJE */
-{"Macedonia_KJE", 0x06bc}, /* U+040C CYRILLIC CAPITAL LETTER KJE */
-{"ncedilla", 0x03f1}, /* U+0146 LATIN SMALL LETTER N WITH CEDILLA */
-{"Ncedilla", 0x03d1}, /* U+0145 LATIN CAPITAL LETTER N WITH CEDILLA */
-{"oe", 0x13bd}, /* U+0153 LATIN SMALL LIGATURE OE */
-{"OE", 0x13bc}, /* U+0152 LATIN CAPITAL LIGATURE OE */
-{"ogonek", 0x01b2}, /* U+02DB OGONEK */
-{"omacron", 0x03f2}, /* U+014D LATIN SMALL LETTER O WITH MACRON */
-{"Omacron", 0x03d2}, /* U+014C LATIN CAPITAL LETTER O WITH MACRON */
-{"oneeighth", 0x0ac3}, /* U+215B VULGAR FRACTION ONE EIGHTH */
-{"rcedilla", 0x03b3}, /* U+0157 LATIN SMALL LETTER R WITH CEDILLA */
-{"Rcedilla", 0x03a3}, /* U+0156 LATIN CAPITAL LETTER R WITH CEDILLA */
-{"rightarrow", 0x08fd}, /* U+2192 RIGHTWARDS ARROW */
-{"rightdoublequotemark", 0x0ad3}, /* U+201D RIGHT DOUBLE QUOTATION MARK */
-{"Scaron", 0x01a9}, /* U+0160 LATIN CAPITAL LETTER S WITH CARON */
-{"scedilla", 0x01ba}, /* U+015F LATIN SMALL LETTER S WITH CEDILLA */
-{"Scedilla", 0x01aa}, /* U+015E LATIN CAPITAL LETTER S WITH CEDILLA */
-{"semivoicedsound", 0x04df}, /* U+309C KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */
-{"seveneighths", 0x0ac6}, /* U+215E VULGAR FRACTION SEVEN EIGHTHS */
-{"Thai_baht", 0x0ddf}, /* U+0E3F THAI CURRENCY SYMBOL BAHT */
-{"Thai_bobaimai", 0x0dba}, /* U+0E1A THAI CHARACTER BO BAIMAI */
-{"Thai_chochan", 0x0da8}, /* U+0E08 THAI CHARACTER CHO CHAN */
-{"Thai_chochang", 0x0daa}, /* U+0E0A THAI CHARACTER CHO CHANG */
-{"Thai_choching", 0x0da9}, /* U+0E09 THAI CHARACTER CHO CHING */
-{"Thai_chochoe", 0x0dac}, /* U+0E0C THAI CHARACTER CHO CHOE */
-{"Thai_dochada", 0x0dae}, /* U+0E0E THAI CHARACTER DO CHADA */
-{"Thai_dodek", 0x0db4}, /* U+0E14 THAI CHARACTER DO DEK */
-{"Thai_fofa", 0x0dbd}, /* U+0E1D THAI CHARACTER FO FA */
-{"Thai_fofan", 0x0dbf}, /* U+0E1F THAI CHARACTER FO FAN */
-{"Thai_hohip", 0x0dcb}, /* U+0E2B THAI CHARACTER HO HIP */
-{"Thai_honokhuk", 0x0dce}, /* U+0E2E THAI CHARACTER HO NOKHUK */
-{"Thai_khokhai", 0x0da2}, /* U+0E02 THAI CHARACTER KHO KHAI */
-{"Thai_khokhon", 0x0da5}, /* U+0E05 THAI CHARACTER KHO KHON */
-{"Thai_khokhuat", 0x0da3}, /* U+0E03 THAI CHARACTER KHO KHUAT */
-{"Thai_khokhwai", 0x0da4}, /* U+0E04 THAI CHARACTER KHO KHWAI */
-{"Thai_khorakhang", 0x0da6}, /* U+0E06 THAI CHARACTER KHO RAKHANG */
-{"Thai_kokai", 0x0da1}, /* U+0E01 THAI CHARACTER KO KAI */
-{"Thai_lakkhangyao", 0x0de5}, /* U+0E45 THAI CHARACTER LAKKHANGYAO */
-{"Thai_lekchet", 0x0df7}, /* U+0E57 THAI DIGIT SEVEN */
-{"Thai_lekha", 0x0df5}, /* U+0E55 THAI DIGIT FIVE */
-{"Thai_lekhok", 0x0df6}, /* U+0E56 THAI DIGIT SIX */
-{"Thai_lekkao", 0x0df9}, /* U+0E59 THAI DIGIT NINE */
-{"Thai_leknung", 0x0df1}, /* U+0E51 THAI DIGIT ONE */
-{"Thai_lekpaet", 0x0df8}, /* U+0E58 THAI DIGIT EIGHT */
-{"Thai_leksam", 0x0df3}, /* U+0E53 THAI DIGIT THREE */
-{"Thai_leksi", 0x0df4}, /* U+0E54 THAI DIGIT FOUR */
-{"Thai_leksong", 0x0df2}, /* U+0E52 THAI DIGIT TWO */
-{"Thai_leksun", 0x0df0}, /* U+0E50 THAI DIGIT ZERO */
-{"Thai_lochula", 0x0dcc}, /* U+0E2C THAI CHARACTER LO CHULA */
-{"Thai_loling", 0x0dc5}, /* U+0E25 THAI CHARACTER LO LING */
-{"Thai_lu", 0x0dc6}, /* U+0E26 THAI CHARACTER LU */
-{"Thai_maichattawa", 0x0deb}, /* U+0E4B THAI CHARACTER MAI CHATTAWA */
-{"Thai_maiek", 0x0de8}, /* U+0E48 THAI CHARACTER MAI EK */
-{"Thai_maihanakat", 0x0dd1}, /* U+0E31 THAI CHARACTER MAI HAN-AKAT */
-{"Thai_maitaikhu", 0x0de7}, /* U+0E47 THAI CHARACTER MAITAIKHU */
-{"Thai_maitho", 0x0de9}, /* U+0E49 THAI CHARACTER MAI THO */
-{"Thai_maitri", 0x0dea}, /* U+0E4A THAI CHARACTER MAI TRI */
-{"Thai_maiyamok", 0x0de6}, /* U+0E46 THAI CHARACTER MAIYAMOK */
-{"Thai_moma", 0x0dc1}, /* U+0E21 THAI CHARACTER MO MA */
-{"Thai_ngongu", 0x0da7}, /* U+0E07 THAI CHARACTER NGO NGU */
-{"Thai_nikhahit", 0x0ded}, /* U+0E4D THAI CHARACTER NIKHAHIT */
-{"Thai_nonen", 0x0db3}, /* U+0E13 THAI CHARACTER NO NEN */
-{"Thai_nonu", 0x0db9}, /* U+0E19 THAI CHARACTER NO NU */
-{"Thai_oang", 0x0dcd}, /* U+0E2D THAI CHARACTER O ANG */
-{"Thai_paiyannoi", 0x0dcf}, /* U+0E2F THAI CHARACTER PAIYANNOI */
-{"Thai_phinthu", 0x0dda}, /* U+0E3A THAI CHARACTER PHINTHU */
-{"Thai_phophan", 0x0dbe}, /* U+0E1E THAI CHARACTER PHO PHAN */
-{"Thai_phophung", 0x0dbc}, /* U+0E1C THAI CHARACTER PHO PHUNG */
-{"Thai_phosamphao", 0x0dc0}, /* U+0E20 THAI CHARACTER PHO SAMPHAO */
-{"Thai_popla", 0x0dbb}, /* U+0E1B THAI CHARACTER PO PLA */
-{"Thai_rorua", 0x0dc3}, /* U+0E23 THAI CHARACTER RO RUA */
-{"Thai_ru", 0x0dc4}, /* U+0E24 THAI CHARACTER RU */
-{"Thai_saraa", 0x0dd0}, /* U+0E30 THAI CHARACTER SARA A */
-{"Thai_saraaa", 0x0dd2}, /* U+0E32 THAI CHARACTER SARA AA */
-{"Thai_saraae", 0x0de1}, /* U+0E41 THAI CHARACTER SARA AE */
-{"Thai_saraaimaimalai", 0x0de4}, /* U+0E44 THAI CHARACTER SARA AI MAIMALAI */
-{"Thai_saraaimaimuan", 0x0de3}, /* U+0E43 THAI CHARACTER SARA AI MAIMUAN */
-{"Thai_saraam", 0x0dd3}, /* U+0E33 THAI CHARACTER SARA AM */
-{"Thai_sarae", 0x0de0}, /* U+0E40 THAI CHARACTER SARA E */
-{"Thai_sarai", 0x0dd4}, /* U+0E34 THAI CHARACTER SARA I */
-{"Thai_saraii", 0x0dd5}, /* U+0E35 THAI CHARACTER SARA II */
-{"Thai_sarao", 0x0de2}, /* U+0E42 THAI CHARACTER SARA O */
-{"Thai_sarau", 0x0dd8}, /* U+0E38 THAI CHARACTER SARA U */
-{"Thai_saraue", 0x0dd6}, /* U+0E36 THAI CHARACTER SARA UE */
-{"Thai_sarauee", 0x0dd7}, /* U+0E37 THAI CHARACTER SARA UEE */
-{"Thai_sarauu", 0x0dd9}, /* U+0E39 THAI CHARACTER SARA UU */
-{"Thai_sorusi", 0x0dc9}, /* U+0E29 THAI CHARACTER SO RUSI */
-{"Thai_sosala", 0x0dc8}, /* U+0E28 THAI CHARACTER SO SALA */
-{"Thai_soso", 0x0dab}, /* U+0E0B THAI CHARACTER SO SO */
-{"Thai_sosua", 0x0dca}, /* U+0E2A THAI CHARACTER SO SUA */
-{"Thai_thanthakhat", 0x0dec}, /* U+0E4C THAI CHARACTER THANTHAKHAT */
-{"Thai_thonangmontho", 0x0db1}, /* U+0E11 THAI CHARACTER THO NANGMONTHO */
-{"Thai_thophuthao", 0x0db2}, /* U+0E12 THAI CHARACTER THO PHUTHAO */
-{"Thai_thothahan", 0x0db7}, /* U+0E17 THAI CHARACTER THO THAHAN */
-{"Thai_thothan", 0x0db0}, /* U+0E10 THAI CHARACTER THO THAN */
-{"Thai_thothong", 0x0db8}, /* U+0E18 THAI CHARACTER THO THONG */
-{"Thai_thothung", 0x0db6}, /* U+0E16 THAI CHARACTER THO THUNG */
-{"Thai_topatak", 0x0daf}, /* U+0E0F THAI CHARACTER TO PATAK */
-{"Thai_totao", 0x0db5}, /* U+0E15 THAI CHARACTER TO TAO */
-{"Thai_wowaen", 0x0dc7}, /* U+0E27 THAI CHARACTER WO WAEN */
-{"Thai_yoyak", 0x0dc2}, /* U+0E22 THAI CHARACTER YO YAK */
-{"Thai_yoying", 0x0dad}, /* U+0E0D THAI CHARACTER YO YING */
-{"threeeighths", 0x0ac4}, /* U+215C VULGAR FRACTION THREE EIGHTHS */
-{"trademark", 0x0ac9}, /* U+2122 TRADE MARK SIGN */
-{"tslash", 0x03bc}, /* U+0167 LATIN SMALL LETTER T WITH STROKE */
-{"Tslash", 0x03ac}, /* U+0166 LATIN CAPITAL LETTER T WITH STROKE */
-{"umacron", 0x03fe}, /* U+016B LATIN SMALL LETTER U WITH MACRON */
-{"Umacron", 0x03de}, /* U+016A LATIN CAPITAL LETTER U WITH MACRON */
-{"uogonek", 0x03f9}, /* U+0173 LATIN SMALL LETTER U WITH OGONEK */
-{"Uogonek", 0x03d9}, /* U+0172 LATIN CAPITAL LETTER U WITH OGONEK */
-{"uparrow", 0x08fc}, /* U+2191 UPWARDS ARROW */
-{"voicedsound", 0x04de}, /* U+309B KATAKANA-HIRAGANA VOICED SOUND MARK */
-{"Zcaron", 0x01ae}, /* U+017D LATIN CAPITAL LETTER Z WITH CARON */
-
-{NULL,0},
-};
diff --git a/qemu/ui/x_keymap.c b/qemu/ui/x_keymap.c
deleted file mode 100644
index 27884851d..000000000
--- a/qemu/ui/x_keymap.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * QEMU SDL display driver
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "x_keymap.h"
-
-static const uint8_t x_keycode_to_pc_keycode[115] = {
- 0xc7, /* 97 Home */
- 0xc8, /* 98 Up */
- 0xc9, /* 99 PgUp */
- 0xcb, /* 100 Left */
- 0x4c, /* 101 KP-5 */
- 0xcd, /* 102 Right */
- 0xcf, /* 103 End */
- 0xd0, /* 104 Down */
- 0xd1, /* 105 PgDn */
- 0xd2, /* 106 Ins */
- 0xd3, /* 107 Del */
- 0x9c, /* 108 Enter */
- 0x9d, /* 109 Ctrl-R */
- 0x0, /* 110 Pause */
- 0xb7, /* 111 Print */
- 0xb5, /* 112 Divide */
- 0xb8, /* 113 Alt-R */
- 0xc6, /* 114 Break */
- 0x0, /* 115 */
- 0x0, /* 116 */
- 0x0, /* 117 */
- 0x0, /* 118 */
- 0x0, /* 119 */
- 0x0, /* 120 */
- 0x0, /* 121 */
- 0x0, /* 122 */
- 0x0, /* 123 */
- 0x0, /* 124 */
- 0x0, /* 125 */
- 0x0, /* 126 */
- 0x0, /* 127 */
- 0x0, /* 128 */
- 0x79, /* 129 Henkan */
- 0x0, /* 130 */
- 0x7b, /* 131 Muhenkan */
- 0x0, /* 132 */
- 0x7d, /* 133 Yen */
- 0x0, /* 134 */
- 0x0, /* 135 */
- 0x47, /* 136 KP_7 */
- 0x48, /* 137 KP_8 */
- 0x49, /* 138 KP_9 */
- 0x4b, /* 139 KP_4 */
- 0x4c, /* 140 KP_5 */
- 0x4d, /* 141 KP_6 */
- 0x4f, /* 142 KP_1 */
- 0x50, /* 143 KP_2 */
- 0x51, /* 144 KP_3 */
- 0x52, /* 145 KP_0 */
- 0x53, /* 146 KP_. */
- 0x47, /* 147 KP_HOME */
- 0x48, /* 148 KP_UP */
- 0x49, /* 149 KP_PgUp */
- 0x4b, /* 150 KP_Left */
- 0x4c, /* 151 KP_ */
- 0x4d, /* 152 KP_Right */
- 0x4f, /* 153 KP_End */
- 0x50, /* 154 KP_Down */
- 0x51, /* 155 KP_PgDn */
- 0x52, /* 156 KP_Ins */
- 0x53, /* 157 KP_Del */
-};
-
-/* This table is generated based off the xfree86 -> scancode mapping above
- * and the keycode mappings in /usr/share/X11/xkb/keycodes/evdev
- * and /usr/share/X11/xkb/keycodes/xfree86
- */
-
-static const uint8_t evdev_keycode_to_pc_keycode[61] = {
- 0x73, /* 97 EVDEV - RO ("Internet" Keyboards) */
- 0, /* 98 EVDEV - KATA (Katakana) */
- 0, /* 99 EVDEV - HIRA (Hiragana) */
- 0x79, /* 100 EVDEV - HENK (Henkan) */
- 0x70, /* 101 EVDEV - HKTG (Hiragana/Katakana toggle) */
- 0x7b, /* 102 EVDEV - MUHE (Muhenkan) */
- 0, /* 103 EVDEV - JPCM (KPJPComma) */
- 0x9c, /* 104 KPEN */
- 0x9d, /* 105 RCTL */
- 0xb5, /* 106 KPDV */
- 0xb7, /* 107 PRSC */
- 0xb8, /* 108 RALT */
- 0, /* 109 EVDEV - LNFD ("Internet" Keyboards) */
- 0xc7, /* 110 HOME */
- 0xc8, /* 111 UP */
- 0xc9, /* 112 PGUP */
- 0xcb, /* 113 LEFT */
- 0xcd, /* 114 RGHT */
- 0xcf, /* 115 END */
- 0xd0, /* 116 DOWN */
- 0xd1, /* 117 PGDN */
- 0xd2, /* 118 INS */
- 0xd3, /* 119 DELE */
- 0, /* 120 EVDEV - I120 ("Internet" Keyboards) */
- 0, /* 121 EVDEV - MUTE */
- 0, /* 122 EVDEV - VOL- */
- 0, /* 123 EVDEV - VOL+ */
- 0, /* 124 EVDEV - POWR */
- 0, /* 125 EVDEV - KPEQ */
- 0, /* 126 EVDEV - I126 ("Internet" Keyboards) */
- 0, /* 127 EVDEV - PAUS */
- 0, /* 128 EVDEV - ???? */
- 0x7e, /* 129 EVDEV - KP_COMMA (brazilian) */
- 0xf1, /* 130 EVDEV - HNGL (Korean Hangul Latin toggle) */
- 0xf2, /* 131 EVDEV - HJCV (Korean Hangul Hanja toggle) */
- 0x7d, /* 132 AE13 (Yen)*/
- 0xdb, /* 133 EVDEV - LWIN */
- 0xdc, /* 134 EVDEV - RWIN */
- 0xdd, /* 135 EVDEV - MENU */
- 0, /* 136 EVDEV - STOP */
- 0, /* 137 EVDEV - AGAI */
- 0, /* 138 EVDEV - PROP */
- 0, /* 139 EVDEV - UNDO */
- 0, /* 140 EVDEV - FRNT */
- 0, /* 141 EVDEV - COPY */
- 0, /* 142 EVDEV - OPEN */
- 0, /* 143 EVDEV - PAST */
- 0, /* 144 EVDEV - FIND */
- 0, /* 145 EVDEV - CUT */
- 0, /* 146 EVDEV - HELP */
- 0, /* 147 EVDEV - I147 */
- 0, /* 148 EVDEV - I148 */
- 0, /* 149 EVDEV - I149 */
- 0, /* 150 EVDEV - I150 */
- 0, /* 151 EVDEV - I151 */
- 0, /* 152 EVDEV - I152 */
- 0, /* 153 EVDEV - I153 */
- 0, /* 154 EVDEV - I154 */
- 0, /* 155 EVDEV - I156 */
- 0, /* 156 EVDEV - I157 */
- 0, /* 157 EVDEV - I158 */
-};
-
-uint8_t translate_xfree86_keycode(const int key)
-{
- return x_keycode_to_pc_keycode[key];
-}
-
-uint8_t translate_evdev_keycode(const int key)
-{
- return evdev_keycode_to_pc_keycode[key];
-}
diff --git a/qemu/ui/x_keymap.h b/qemu/ui/x_keymap.h
deleted file mode 100644
index afde2e94b..000000000
--- a/qemu/ui/x_keymap.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * QEMU SDL display driver
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef QEMU_X_KEYMAP_H
-#define QEMU_X_KEYMAP_H
-
-uint8_t translate_xfree86_keycode(const int key);
-
-uint8_t translate_evdev_keycode(const int key);
-
-#endif