d0d7708ba2
Typically a UNIX guest OS will log boot messages to a serial port in addition to any graphical console. An admin user may also wish to use the serial port for an interactive console. A virtualization management system may wish to collect system boot messages by logging the serial port, but also wish to allow admins interactive access. Currently providing such a feature forces the mgmt app to either provide 2 separate serial ports, one for logging boot messages and one for interactive console login, or to proxy all output via a separate service that can multiplex the two needs onto one serial port. While both are valid approaches, they each have their own downsides. The former causes confusion and extra setup work for VM admins creating disk images. The latter places an extra burden to re-implement much of the QEMU chardev backends logic in libvirt or even higher level mgmt apps and adds extra hops in the data transfer path. A simpler approach that is satisfactory for many use cases is to allow the QEMU chardev backends to have a "logfile" property associated with them. $QEMU -chardev socket,host=localhost,port=9000,\ server=on,nowait,id-charserial0,\ logfile=/var/log/libvirt/qemu/test-serial0.log -device isa-serial,chardev=charserial0,id=serial0 This patch introduces a 'ChardevCommon' struct which is setup as a base for all the ChardevBackend types. Ideally this would be registered directly as a base against ChardevBackend, rather than each type, but the QAPI generator doesn't allow that since the ChardevBackend is a non-discriminated union. The ChardevCommon struct provides the optional 'logfile' parameter, as well as 'logappend' which controls whether QEMU truncates or appends (default truncate). Signed-off-by: Daniel P. Berrange <berrange@redhat.com> Message-Id: <1452516281-27519-1-git-send-email-berrange@redhat.com> [Call qemu_chr_parse_common if cd->parse is NULL. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
94 lines
3.1 KiB
C
94 lines
3.1 KiB
C
/*
|
|
* QEMU Microsoft serial mouse emulation
|
|
*
|
|
* Copyright (c) 2008 Lubomir Rintel
|
|
*
|
|
* 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 <stdlib.h>
|
|
#include "qemu-common.h"
|
|
#include "sysemu/char.h"
|
|
#include "ui/console.h"
|
|
|
|
#define MSMOUSE_LO6(n) ((n) & 0x3f)
|
|
#define MSMOUSE_HI2(n) (((n) & 0xc0) >> 6)
|
|
|
|
static void msmouse_event(void *opaque,
|
|
int dx, int dy, int dz, int buttons_state)
|
|
{
|
|
CharDriverState *chr = (CharDriverState *)opaque;
|
|
|
|
unsigned char bytes[4] = { 0x40, 0x00, 0x00, 0x00 };
|
|
|
|
/* Movement deltas */
|
|
bytes[0] |= (MSMOUSE_HI2(dy) << 2) | MSMOUSE_HI2(dx);
|
|
bytes[1] |= MSMOUSE_LO6(dx);
|
|
bytes[2] |= MSMOUSE_LO6(dy);
|
|
|
|
/* Buttons */
|
|
bytes[0] |= (buttons_state & 0x01 ? 0x20 : 0x00);
|
|
bytes[0] |= (buttons_state & 0x02 ? 0x10 : 0x00);
|
|
bytes[3] |= (buttons_state & 0x04 ? 0x20 : 0x00);
|
|
|
|
/* We always send the packet of, so that we do not have to keep track
|
|
of previous state of the middle button. This can potentially confuse
|
|
some very old drivers for two button mice though. */
|
|
qemu_chr_be_write(chr, bytes, 4);
|
|
}
|
|
|
|
static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, int len)
|
|
{
|
|
/* Ignore writes to mouse port */
|
|
return len;
|
|
}
|
|
|
|
static void msmouse_chr_close (struct CharDriverState *chr)
|
|
{
|
|
g_free (chr);
|
|
}
|
|
|
|
static CharDriverState *qemu_chr_open_msmouse(const char *id,
|
|
ChardevBackend *backend,
|
|
ChardevReturn *ret,
|
|
Error **errp)
|
|
{
|
|
ChardevCommon *common = qapi_ChardevDummy_base(backend->u.msmouse);
|
|
CharDriverState *chr;
|
|
|
|
chr = qemu_chr_alloc(common, errp);
|
|
if (!chr) {
|
|
return NULL;
|
|
}
|
|
chr->chr_write = msmouse_chr_write;
|
|
chr->chr_close = msmouse_chr_close;
|
|
chr->explicit_be_open = true;
|
|
|
|
qemu_add_mouse_event_handler(msmouse_event, chr, 0, "QEMU Microsoft Mouse");
|
|
|
|
return chr;
|
|
}
|
|
|
|
static void register_types(void)
|
|
{
|
|
register_char_driver("msmouse", CHARDEV_BACKEND_KIND_MSMOUSE, NULL,
|
|
qemu_chr_open_msmouse);
|
|
}
|
|
|
|
type_init(register_types);
|