#define SCREEN_SIZE (BYTES_PER_ROW * NUM_ROWS)
-struct cons_state
-{
+struct cons_state {
v3_console_t cons;
struct vm_device * frontend_dev;
};
{
struct vm_device *dev = (struct vm_device *) private_data;
struct cons_state *state = (struct cons_state *) dev->private_data;
- uint_t offset = (x * BYTES_PER_COL) + (y * BYTES_PER_ROW);
+ uint_t offset;
uint_t last_x, last_y;
+ /* avoid out-of-range coordinates */
+ if (x >= NUM_COLS) x = NUM_COLS - 1;
+ if (y >= NUM_ROWS) y = NUM_ROWS - 1;
+ offset = (x * BYTES_PER_COL) + (y * BYTES_PER_ROW);
+
/* unfortunately Palacios sometimes misses some writes,
* but if they are accompanied by a cursor move we may be able to
* detect this
}
static int screen_update(uint_t x, uint_t y, uint_t length, void * private_data) {
- struct vm_device *dev = (struct vm_device *)private_data;
- struct cons_state *state = (struct cons_state *)dev->private_data;
+ struct vm_device * dev = (struct vm_device *)private_data;
+ struct cons_state * state = (struct cons_state *)dev->private_data;
uint_t offset = (x * BYTES_PER_COL) + (y * BYTES_PER_ROW);
uint8_t fb_buf[length];
int i;
return 0;
}
+
+static int cons_free(struct cons_state * state) {
+ v3_console_close(state->cons);
+
+ // remove host event
+
+ V3_Free(state);
+
+ return 0;
+}
+
+static int console_event_handler(struct v3_vm_info * vm,
+ struct v3_console_event * evt,
+ void * priv_data) {
+ screen_update(0, 0, SCREEN_SIZE, priv_data);
+
+ return 0;
+}
+
static struct v3_console_ops cons_ops = {
.update_screen = screen_update,
.update_cursor = cursor_update,
};
static struct v3_device_ops dev_ops = {
- .free = NULL,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
+ .free = (int (*)(void *))cons_free,
};
static int cons_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg)
state->frontend_dev = frontend;
/* open tty for screen display */
- state->cons = v3_console_open(vm);
+ state->cons = v3_console_open(vm, NUM_COLS, NUM_ROWS);
if (!state->cons) {
PrintError("Could not open console\n");
}
/* allocate device */
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
- V3_ASSERT(dev);
-
- /* attach device to virtual machine */
- if (v3_attach_device(vm, dev) == -1) {
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state);
+
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
V3_Free(state);
return -1;
/* attach to front-end display adapter */
v3_console_register_cga(frontend, &cons_ops, dev);
+ v3_hook_host_event(vm, HOST_CONSOLE_EVT, V3_HOST_EVENT_HANDLER(console_event_handler), dev);
+
return 0;
}