#
# Libraries that we need to build
#
-LIBS = libv3_user_host_dev.a libv3_user_keyed_stream.a libv3_ctrl.a libv3_guest_mem.a
+LIBS = libv3_user_host_dev.a libv3_user_keyed_stream.a libv3_ctrl.a libv3_guest_mem.a libv3_fb.a
BUILD_EXECS = $(BASE_EXECS) $(EXAMPLE_EXECS) $(EXPERIMENTAL_EXECS)
BUILD_LIBS = $(LIBS)
$(CC) $(CFLAGS) $< -L. -lv3_guest_mem -o $@
+#
+# FB (Graphics Console) user interface library (needed for VNC access
+# to GC - also wraps mouse and keyboard event delivery)
+libv3_fb.a : v3_fb.c v3_fb.h
+ $(CC) $(CFLAGS) -I../linux_module -c v3_fb.c
+ $(AR) ruv libv3_fb.a v3_fb.o
+ rm -rf v3_fb.o
+
+
#
# VNC support is compiled separately
--- /dev/null
+#include "v3_fb.h"
+
+
+// This is the data structure that is passed back and forth with user-land
+// ioctl
+#define V3_VM_FB_INPUT 256+1
+struct v3_fb_input {
+ enum { V3_FB_KEY, V3_FB_MOUSE, V3_FB_BOTH} data_type;
+ uint8_t scan_code;
+ uint8_t mouse_data[3];
+};
+
+#define V3_VM_FB_QUERY 256+2
+#define __user
+struct v3_fb_query_response {
+ enum e { V3_FB_DATA_ALL, V3_FB_DATA_BOX, V3_FB_UPDATE, V3_FB_SPEC } request_type;
+ struct v3_frame_buffer_spec spec; // in: desired spec; out: actual spec
+ uint32_t x, y, w, h; // region to copy (0s = all) in/out args
+ int updated; // whether this region has been updated or not
+ void __user *data; // user space pointer to copy data to
+};
+
+int v3_send_key(int fd, uint8_t scan_code)
+{
+ struct v3_fb_input e;
+
+ e.data_type=V3_FB_KEY;
+ e.scan_code=scan_code;
+
+ if (ioctl(fd,V3_VM_FB_INPUT,&e)<0) {
+ perror("v3_send_key");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int v3_send_mouse(int fd, uint8_t mx, uint8_t my, uint8_t button)
+{
+ struct v3_fb_input e;
+
+ e.data_type=V3_FB_MOUSE;
+ e.mouse_data[0]=mx;
+ e.mouse_data[1]=my;
+ e.mouse_data[2]=button;
+
+ if (ioctl(fd,V3_VM_FB_INPUT,&e)<0) {
+ perror("v3_send_mouse");
+ return -1;
+ }
+
+ return 0;
+}
+
+int v3_get_fb_spec(int fd, struct v3_frame_buffer_spec *spec)
+{
+ struct v3_fb_query_response q;
+
+ q.request_type=V3_FB_SPEC;
+
+ if (ioctl(fd,V3_VM_FB_QUERY,&q)<0) {
+ perror("v3_get_fb_spec");
+ return -1;
+
+ }
+
+ *spec = q.spec;
+
+ return 0;
+}
+
+int v3_get_fb_data(int fd, struct v3_frame_buffer_spec *spec, void *data)
+{
+ struct v3_fb_query_response q;
+
+ q.request_type=V3_FB_DATA_ALL;
+ q.spec=*spec;
+ q.data=data;
+
+ if (ioctl(fd,V3_VM_FB_QUERY,&q)<0) {
+ perror("v3_get_fb_data");
+ return -1;
+ }
+
+ *spec = q.spec;
+
+ return 0;
+
+}
+
+int v3_have_update(int fd)
+{
+ struct v3_fb_query_response q;
+ int updated;
+
+ q.request_type=V3_FB_UPDATE;
+ q.x=0;
+ q.y=0;
+ q.w=(uint32_t) -1;
+ q.h=(uint32_t) -1;
+
+ if (ioctl(fd,V3_VM_FB_QUERY,&q)<0) {
+ perror("v3_get_fb_data");
+ return -1;
+ }
+
+ return q.updated;
+
+}
--- /dev/null
+#ifndef __v3_fb_h__
+#define __v3_fb_h__
+
+#ifdef __cplusplus
+#define EXTERNC extern "C"
+#else
+#define EXTERNC
+#endif
+
+#include <stdint.h>
+
+
+EXTERNC struct v3_frame_buffer_spec {
+ uint32_t height;
+ uint32_t width;
+ uint8_t bytes_per_pixel;
+ uint8_t bits_per_channel;
+ uint8_t red_offset; // byte offset in pixel to get to red channel
+ uint8_t green_offset; // byte offset in pixel to get to green channel
+ uint8_t blue_offset; // byte offset in pixel to get to blue channel
+};
+
+EXTERNC int v3_get_fb_spec(int fd, struct v3_frame_buffer_spec *spec);
+EXTERNC int v3_have_update(int fd);
+EXTERNC int v3_get_fb_data(int fd, struct v3_frame_buffer_spec *spec, void *data);
+
+
+EXTERNC int v3_send_key(int fd, uint8_t scan_code);
+EXTERNC int v3_send_mouse(int fd, uint8_t mx, uint8_t my, uint8_t button);
+
+
+
+#endif