uint32_t num_updates;
- // Currently keystrokes and mouse movements are ignored
+ int change_request;
+
+ int (*render_request)(v3_graphics_console_t cons,
+ void *priv_data);
+ void *render_data;
+
+ int (*update_inquire)(v3_graphics_console_t cons,
+ void *priv_data);
+
+ void *update_data;
- // currently, we will not worry about locking this
- // lock_t ...
};
static int g_changed(v3_graphics_console_t cons)
{
-#if 0
struct palacios_graphics_console *gc =
(struct palacios_graphics_console *) cons;
+ int cr;
+
+ cr = gc->change_request;
+
+ gc->change_request=0;
- int rc = !(gc->num_updates % 1000);
-
gc->num_updates++;
- return rc;
-#else
- return 1;
-#endif
+ return cr;
+
+}
+
+
+static int g_register_render_request(
+ v3_graphics_console_t cons,
+ int (*render_request)(v3_graphics_console_t,
+ void *),
+ void *priv_data)
+{
+ struct palacios_graphics_console *gc =
+ (struct palacios_graphics_console *) cons;
+
+ gc->render_data = priv_data;
+ gc->render_request = render_request;
+
+ printk("palacios: installed rendering callback function for graphics console\n");
+
+ return 0;
+
}
+static int g_register_update_inquire(
+ v3_graphics_console_t cons,
+ int (*update_inquire)(v3_graphics_console_t,
+ void *),
+ void *priv_data)
+{
+ struct palacios_graphics_console *gc =
+ (struct palacios_graphics_console *) cons;
+
+ gc->update_data = priv_data;
+ gc->update_inquire = update_inquire;
+
+ printk("palacios: installed update inquiry callback function for graphics console\n");
+
+ return 0;
+}
static int palacios_graphics_console_key(struct v3_guest * guest,
struct palacios_graphics_console *cons,
e.status = 0;
e.scan_code = scancode;
+ //printk("palacios: start key delivery\n");
+
v3_deliver_keyboard_event(guest->v3_ctx, &e);
+
+ //printk("palacios: end key delivery\n");
return 0;
}
e.data[1]=y;
e.data[2]=buttons; // These three are completely wrong, of course - ignoring mouse for now
- v3_deliver_mouse_event(guest->v3_ctx,&e);
+ // mouse delivery is broken, so don't do it.
+ // v3_deliver_mouse_event(guest->v3_ctx,&e);
return 0;
}
.release_data_rw = g_release_data_rw,
.changed = g_changed,
+ .register_render_request = g_register_render_request,
+ .register_update_inquire = g_register_update_inquire,
};
switch (q.request_type) {
case V3_FB_SPEC:
+ //printk("palacios: request for db spec from Userland\n");
// returns only the spec for the FB
q.spec = cons->spec;
break;
case V3_FB_UPDATE:
+ //printk("palacios: test for fb updatei from Userland\n");
// returns whether an update is available for the region
- // currently always true
- q.updated = 1;
+ if (cons->update_inquire) {
+ q.updated = cons->update_inquire(cons,cons->update_data);
+ } else {
+ q.updated = 1;
+ }
+ //printk("palacios: update=%d\n",q.updated);
+
+ // request a render, since a FB_DATA will probably soon come
+ cons->change_request = 1;
break;
break;
case V3_FB_DATA_ALL: {
+ //printk("palacios: got FrameBuffer Request from Userland\n");
// First let's sanity check to see if they are requesting the same
// spec that we have
if (memcmp(&(q.spec),&(cons->spec),sizeof(struct v3_frame_buffer_spec))) {
printk("palacios: request for data with non-matching fb spec \n");
return -EFAULT;
}
+ // Now we will force a render if we can
+ if (cons->render_request) {
+ //printk("palacios: making rendering request\n");
+ cons->render_request(cons,cons->render_data);
+ }
+
// Now let's indicate an update is in the pointer and copy across the data
if (copy_to_user(q.data,cons->data,cons->spec.width*cons->spec.height*cons->spec.bytes_per_pixel)) {
printk("palacios: unable to copy fb content to user\n");
return -EFAULT;
}
+ //printk("palacios: FrameBuffer copy out done\n");
q.updated = 1;
+ // Now we don't need to request a render
+ cons->change_request = 0;
}
break;
printk("palacios: copy from user in getting input in fb\n");
return -EFAULT;
}
+
+ //printk("palacios: input from Userland\n");
if ((inp.data_type == V3_FB_KEY) || (inp.data_type == V3_FB_BOTH)) {
rc = palacios_graphics_console_key(guest, cons, inp.scan_code);
+ //printk("palacios: key delivered to palacios\n");
}
if ((inp.data_type == V3_FB_MOUSE) || (inp.data_type == V3_FB_BOTH)) {
rc |= palacios_graphics_console_mouse(guest, cons, inp.mouse_data[0],
inp.mouse_data[1], inp.mouse_data[2]);
+ //printk("palacios: mouse delivered to palacios\n");
}
if (rc) {
return -EFAULT;
} else {
+ cons->change_request=1;
return 0;
}
}
void v3_graphics_console_release_frame_buffer_data_rw(v3_graphics_console_t cons);
// returns >0 if a redraw in response to this update would be useful now
int v3_graphics_console_inform_update(v3_graphics_console_t cons);
+// when render_request is invoked, Palacios will redraw immediately
+int v3_graphics_console_register_render_request(
+ v3_graphics_console_t cons,
+ int (*render_request)(v3_graphics_console_t cons,
+ void *priv_data),
+ void *priv_data);
+// when update_inquire is invoked, palacios will indicate if there
+// is anything new with a non-zero return value
+int v3_graphics_console_register_update_inquire(
+ v3_graphics_console_t cons,
+ int (*update_inquire)(v3_graphics_console_t cons,
+ void *priv_data),
+ void *priv_data);
void v3_graphics_console_close(v3_graphics_console_t cons);
// callback to indicate that the FB is stale and that an update can occur
// a positive return value indicates we should re-render now
+ // this callback is from Palacios to the implementation and is called
+ // when virtual GPU state changes to ask if the FB should be re-rendered now
int (*changed)(v3_graphics_console_t cons);
+
+
+ // callback to allow Palacios to register a render request callback
+ // with the implementation. Using this callback, the implementation
+ // can specifically request that Palacios render immediately
+ int (*register_render_request)(v3_graphics_console_t cons,
+ int (*render_request)(v3_graphics_console_t cons,
+ void *priv_data),
+ void *priv_data);
+
+ // callback to allow Palacios to register an update inquire callback
+ // with the implementation. Using this callback, the implementation
+ // can ask if Palacios has any new data
+ int (*register_update_inquire)(v3_graphics_console_t cons,
+ int (*update_inquire)(v3_graphics_console_t cons,
+ void *priv_data),
+ void *priv_data);
+
};
return graphics_console_hooks->changed(cons);
}
+int v3_graphics_console_register_render_request(
+ v3_graphics_console_t cons,
+ int (*render_request)(v3_graphics_console_t cons,
+ void *priv_data),
+ void *priv_data)
+{
+ V3_ASSERT(graphics_console_hooks!=NULL);
+ V3_ASSERT(graphics_console_hooks->register_render_request!=NULL);
+
+ return graphics_console_hooks->register_render_request(cons,render_request,priv_data);
+}
+
+int v3_graphics_console_register_update_inquire(
+ v3_graphics_console_t cons,
+ int (*update_inquire)(v3_graphics_console_t cons,
+ void *priv_data),
+ void *priv_data)
+{
+ V3_ASSERT(graphics_console_hooks!=NULL);
+ V3_ASSERT(graphics_console_hooks->register_update_inquire!=NULL);
+
+ return graphics_console_hooks->register_update_inquire(cons,update_inquire,priv_data);
+}
+
+
void V3_Init_Graphics_Console(struct v3_graphics_console_hooks * hooks) {
graphics_console_hooks = hooks;
PrintDebug("V3 graphics console inited\n");