qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] Just a thought (high level API)


From: Nathaniel McCallum
Subject: [Qemu-devel] Just a thought (high level API)
Date: Wed, 09 Feb 2005 10:09:04 -0500

I know a lot of people are wanting to build qemu frontends and embedding
the sdl window has been a frustration to several.  Well, I was just
thinking today, what if we moved most of the emulation code behind a
high level api, creating "libqemu" which would allow for lots of things
including multiple frontends, embeded qemu, etc.  I brainstormed up a
*very* raw idea yesterday between my classes while taking a very cursory
glance at the code.  I had three goals:
  1. Create a library (duh!)
  2. Allow for multiple rendering options (SDL, GTK, QT, win32, etc)
  3. Allow for storable virtual machine profiles which could be shared
across all front ends (ie. a virtual machine profile could be used in
QemuX, a Win32 frontend, a GTK frontend, etc...)

Attached below is a header containing a first crack at a libqemu api.

Nathaniel
/* 
 * The basic idea of the API below is to allow Frontends to provide their own
 * method of device control (ie. QEMUDisplayControl) and allowing users to
 * provide the virtual machine settings via a saveable profile.  Thus:
 * ${virtual_machine_profile} + ${device_control} == virtual machine.
 * Advantages a basic library as a backend include:
 *   - Code reuse
 *   - Plugin "drivers" (ie. SDL, Xv, GTK/GDK, QT, etc...)
 *   - Various frontends for different tasks
 *   - Embedded QEMU :)
 *   - Others... 
 * This API is incomplete and is just the result of a brainstorming session.
 * As this idea is version 0.0.0.0.1 ;), feel free to make suggestions, etc.
 */

#ifndef FALSE
#define FALSE 0
#define TRUE !FALSE
typedef int bool;
#endif

#define DISK_TYPE_HDD           0
#define DISK_TYPE_CDROM         1
#define DISK_TYPE_FLOPPY        2

#define NET_TYPE_DUMMY          0
#define NET_TYPE_USER           1
#ifndef _WIN32
#define NET_TYPE_TUN            2
#endif

#define PROTOCOL_UDP            0
#define PROTOCOL_TCP            1

#define FDA                     0
#define FDB                     1
#define HDA                     2
#define HDB                     3
#define HDC                     4
#define HDD                     5


/* 
 * A structure holding the current display state.
 * All members are private and all changes should be made through the methods
 * in QEMUDisplayPlugin (ie. called by libqemu).
 */
typedef struct {
        uint8_t *data;
        int linesize;
        int depth;
        int width;
        int height;
        bool fullscreen;
} QEMUDisplayState;

/* 
 * This struct is basically a plugin for different video sinks.  No matter
 * what output method you are using (SDL,Xv,GDK/GTK,etc), just use this struct
 * to allow QEMU to control your display.
 */
typedef struct {
        /* Initializes the display. Returns FALSE on failure, TRUE on success) 
*/
        bool (*dpy_init) (QEMUDisplayState *ds);
        /* Enters fullscreen mode */
        void (*dpy_fullscreen_on) (QEMUDisplayState *ds);
        /* Exits fullscreen mode */
        void (*dpy_fullscreen_off) (QEMUDisplayState *ds);
        /* Grabs the keyboard and mouse */
        void (*dpy_grab) (QEMUDisplayState *ds);
        /* Releases the keyboard and mouse */
        void (*dpy_ungrab) (QEMUDisplayState *ds);
        /* I'm not really sure what this does... update vs refresh? */
        void (*dpy_update) (QEMUDisplayState *ds);
        /* Resizes the display to specified size */
        void (*dpy_resize) (QEMUDisplayState *ds, int width, int height);
        /* I'm not really sure what this does either... update vs refresh? */
        void (*dpy_refresh) (QEMUDisplayState *ds);
        /* Called upon closing the display.  After calling this, dpy_init must 
         * be called again for any further activity. */
        void (*dpy_end) (QEMUDisplayState *ds);
} QEMUDisplayControl;

/*
 * Structure which represents a drive or drive image.
 */
typedef struct {
        char *device_file;
        int device_type; /* ie. DISK_TYPE_CDROM */
        bool snapshot; /* enables snapshot mode on this device */
} QEMUDriveProfile;

/*
 * Structure representing a redirection
 */
typedef struct {
        int type; /* ie. PROTOCOL_TCP */
        int host_port;
        char *guest_ip;
        int guest_port;
} QEMUNetworkRedirectionProfile;

/*
 * Structure which represents a network setup.
 */
typedef struct {
        /* A NULL terminated vector of mac addresses.  
         * Only first x nics will be allowed (others ignored). */
        uint8_t **macaddr;
        /* The type of network access we will use. */
        int network_type; /* ie. NET_TYPE_USER */
#ifndef _WIN32
        /* The file descriptor of an already open tap/tun interface */
        int tun_fd;
        /* The script used to bring up a tap/tun interface */
        char *tun_script;
        /* Allow tftp access to the files starting with this prefix */
        char *tftp_prefix;
        /* Allow samba access to the files in this dir */
        char *smb_dir;
#endif
        /* A NULL terminated vector of redirections */
        QEMUNetworkRedirectionProfile **redir;
} QEMUNetworkProfile;

/*
 * Represents a Virtual Machine.
 */
typedef struct {
        /**
         *** Metadata
         **/
        /* The name of the virtual machine. */
        char *name;
        
        /**
         *** Core Hardware
         **/
        /* Our drives.  If a particular drive is not set, it *MUST* == NULL 
         * ie. to unset 'hda': x->drives[HDA] = NULL */
        QEMUDriveProfile *drives[6];
        /* Our network setup */
        QEMUNetworkProfile *network;
        /* The ammount of memory for the virtual machine in megabytes */
        int mb_memory;
        
        /**
         *** Hardware options
         **/
        /* Whether or not audio support is enabled. Perhaps we want a 
         * QEMUAudioControl plugin instead (or in addition)? */
        bool enable_audio;
        /* Whether or not to enable localtime for the guest */
        bool guestclock_localtime;
        /* Takes a DISK_TYPE and boots the first device matching that type */
        int boot_type; /* ie. DISK_TYPE_CDROM */
        /* The keyboard map to use. */
        char *keyboard_map;
        /* Whether or not to start the Virtual Machine in fullscreen mode */
        bool fullscreen_on_start;
        /* Enables pci emulation */
        bool emulate_pci;
        
        /**
         *** Boot options
         **/
        /* Options for booting a specific kernel */
        char *bzImage;
        char *cmdline;
        char *initrd;
        /* Define custom BIOS locations */
        char *sys_bios;
        char *vga_bios;
} QEMUVirtualMachineProfile;

typedef struct {
        unsigned int id; /* Do we need this? */
        QEMUDisplayControl *display;
        QEMUVirtualMachineProfile *profile;
        bool frozen;
        /* Others? */
} QEMUVirtualMachine;

/* Does any pre-emu tasks including compiling a QEMUVirtualMachine instance.
 * Returns null on failure */
QEMUVirtualMachine *qemu_vm_init (QEMUVirtualMachineProfile *vmp, 
                                QEMUDisplayControl *dc /*,
                                ??QEMUAudioControl *ac?? */);
/* Starts (or resumes) emulation */
void qemu_vm_start(QEMUVirtualMachine *vm);
/* Pauses emulation (use qemu_vm_start() to resume) */
void qemu_vm_pause(QEMUVirtualMachine *vm);
/* Resets virtual machine */
void qemu_vm_reset(QEMUVirtualMachine *vm);
/* Closes virtual machine.  qemu_vm_init() must be called again before 
 * restarting emulation. */
void qemu_vm_quit(QEMUVirtualMachine *vm);

/* Commit snapshots to disk. disk = [FDA|FDB|HDA|HDB|HDC|HDD|-1] */
void qemu_vm_commit(QEMUVirtualMachine *vm, int disk);
/* Ejects a disk */
void qemu_vm_eject(QEMUVirtualMachine *vm, int disk);
/* Dumps the screen to a ppm image */
bool qemu_vm_screendump(QEMUVirtualMachine *vm, char *filename);
/* Save and load the state of the VM */
bool qemu_vm_savevm(QEMUVirtualMachine *vm, char *filename);
bool qemu_vm_loadvm(QEMUVirtualMachine *vm, char *filename);
/* Send keys */
void qemu_vm_sendkey(QEMUVirtualMachine *vm, char *keys);
/* ...and others (ie. gdb stuff, etc)... */

/* A standard way to save and load virtual machines (XML?, .INI-style?).
 * This is usable by all front ends no matter what toolkit. */
QEMUVirtualMachineProfile *qemu_vmp_load(char *filename);
bool qemu_vmp_save(QEMUVirtualMachineProfile *vmp, char *filename);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]