aboutsummaryrefslogtreecommitdiff
path: root/vbox.h
diff options
context:
space:
mode:
Diffstat (limited to 'vbox.h')
-rw-r--r--vbox.h175
1 files changed, 143 insertions, 32 deletions
diff --git a/vbox.h b/vbox.h
index 2b9c826..486058a 100644
--- a/vbox.h
+++ b/vbox.h
@@ -23,53 +23,164 @@
#include <stdbool.h>
#include <stdint.h>
+#include "utils.h"
+#include "vboxdev.h"
+
+//#define VBOX_BUFFER_SIZE 64
+#define VBOX_BUFFER_SIZE (1024 + 32 + 24 + 20)
+
+typedef struct vboxcomm {
+ uint16_t iobase;
+ char buf[VBOX_BUFFER_SIZE];
+ uint32_t buf_physaddr;
+} vboxcomm_t;
+typedef vboxcomm_t __far * LPVBOXCOMM;
+
/** Logs a single character to the VBox debug message port. */
-static void vbox_logc(char c);
-#pragma aux vbox_logc = \
+static void vbox_log_putc(char c);
+#pragma aux vbox_log_putc = \
"mov dx, 0x504" \
"out dx, al" \
__parm [al] \
__modify [dx]
-/** Logs a string to the VBox debug message port. */
-static void vbox_logs(const char __far *str);
-#pragma aux vbox_logs = \
- "mov di, si" \
- "xor cx, cx" \
- "not cx" /* First we have to strlen(str), prepare -1 as max length */ \
- "xor al, al" /* The '\0' that we're searching for */ \
- "cld" \
- "repne scas byte ptr es:[di]" /* afterwards, cx = -(len+2) */ \
- "not cx" /* cx = (len+1) */ \
- "dec cx" /* cx = len */ \
- "mov dx, 0x504" /* And now we can write the string */ \
- "rep outs dx, byte ptr es:[si]" \
- __parm [es si] \
- __modify [ax cx dx si di]
+/** Actually send a request to the VirtualBox VMM device.
+ * @param addr 32-bit physical address containing the VMMDevRequest struct.
+ */
+static void vbox_send_request(uint16_t iobase, uint32_t addr);
+#pragma aux vbox_send_request = \
+ "push eax" /* Preserve 32-bit register, specifically the higher word. */ \
+ "push bx" /* Combine bx:ax into single 32-bit eax */ \
+ "push ax" \
+ "pop eax" \
+ "out dx, eax" \
+ "pop eax" \
+ __parm [dx] [bx ax] \
+ __modify [dx]
+
+extern int vbox_init(LPVBOXCOMM vb);
+
+/** Lets VirtualBox know that there are VirtualBox Guest Additions on this guest.
+ * @param osType os installed on this guest. */
+static inline int vbox_report_guest_info(LPVBOXCOMM vb, uint32_t osType)
+{
+ VMMDevReportGuestInfo __far *req = (void __far *) vb->buf;
+
+ bzero(req, sizeof(VMMDevReportGuestInfo));
+
+ req->header.size = sizeof(VMMDevReportGuestInfo);
+ req->header.version = VMMDEV_REQUEST_HEADER_VERSION;
+ req->header.requestType = VMMDevReq_ReportGuestInfo;
+ req->header.rc = -1;
+ req->guestInfo.interfaceVersion = VMMDEV_VERSION;
+ req->guestInfo.osType = osType;
+
+ vbox_send_request(vb->iobase, vb->buf_physaddr);
+
+ return req->header.rc;
+}
+
+/** Tells VirtualBox whether we want absolute mouse information or not. */
+static inline int vbox_set_mouse(LPVBOXCOMM vb, bool absolute, bool pointer)
+{
+ VMMDevReqMouseStatus __far *req = (void __far *) vb->buf;
+
+ bzero(req, sizeof(VMMDevReqMouseStatus));
+
+ req->header.size = sizeof(VMMDevReqMouseStatus);
+ req->header.version = VMMDEV_REQUEST_HEADER_VERSION;
+ req->header.requestType = VMMDevReq_SetMouseStatus;
+ req->header.rc = -1;
+ if (absolute) req->mouseFeatures |= VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE;
+ if (pointer) req->mouseFeatures |= VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR;
+
+ vbox_send_request(vb->iobase, vb->buf_physaddr);
+
+ return req->header.rc;
+}
+
+/** Gets the current absolute mouse position from VirtualBox.
+ * @param abs false if user has disabled mouse integration in VirtualBox,
+ * in which case we should fallback to PS/2 relative events. */
+static inline int vbox_get_mouse(LPVBOXCOMM vb, bool *abs,
+ uint16_t *xpos, uint16_t *ypos)
+{
+ VMMDevReqMouseStatus __far *req = (void __far *) vb->buf;
+
+ bzero(req, sizeof(VMMDevReqMouseStatus));
+
+ req->header.size = sizeof(VMMDevReqMouseStatus);
+ req->header.version = VMMDEV_REQUEST_HEADER_VERSION;
+ req->header.requestType = VMMDevReq_GetMouseStatus;
+ req->header.rc = -1;
+
+ vbox_send_request(vb->iobase, vb->buf_physaddr);
+
+ *abs = req->mouseFeatures & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE;
+ *xpos = req->pointerXPos;
+ *ypos = req->pointerYPos;
+
+ return req->header.rc;
+}
+
+/** @todo */
+static inline int vbox_set_pointer_visible(LPVBOXCOMM vb, bool visible)
+{
+ VMMDevReqMousePointer __far *req = (void __far *) vb->buf;
+
+ bzero(req, sizeof(VMMDevReqMousePointer));
+
+ req->header.size = sizeof(VMMDevReqMousePointer);
+ req->header.version = VMMDEV_REQUEST_HEADER_VERSION;
+ req->header.requestType = VMMDevReq_SetPointerShape;
+ req->header.rc = -1;
+
+ if (visible) req->fFlags |= VBOX_MOUSE_POINTER_VISIBLE;
+
+ vbox_send_request(vb->iobase, vb->buf_physaddr);
-/** Logs a single character followed by '\n' to force log flush.
- * A life-saver when there is no data segment available. */
-#define vbox_putc(c) do { \
- vbox_logc(c); vbox_logc('\n'); \
- } while (0);
+ return req->header.rc;
+}
-extern int vbox_init(void);
+static inline unsigned vbox_pointer_shape_data_size(unsigned width, unsigned height)
+{
+ //unsigned base_size = 24 + 20;
+ unsigned and_mask_size = (width + 7) / 8 * height;
+ unsigned xor_mask_size = width * height * 4;
+ return ((and_mask_size + 3) & ~3) + xor_mask_size;
+}
-extern int vbox_alloc_buffers(void);
-extern int vbox_free_buffers(void);
+static inline int vbox_set_pointer_shape(LPVBOXCOMM vb,
+ uint16_t xHot, uint16_t yHot,
+ uint16_t width, uint16_t height,
+ char __far *data)
+{
+ VMMDevReqMousePointer __far *req = (void __far *) vb->buf;
+ unsigned data_size = vbox_pointer_shape_data_size(width, height);
+ unsigned full_size = MAX(sizeof(VMMDevReqMousePointer), 24 + 20 + data_size);
-extern int vbox_report_guest_info(uint32_t osType);
+ if (full_size >= VBOX_BUFFER_SIZE) {
+ return -2;
+ }
-extern int vbox_set_filter_mask(uint32_t add, uint32_t remove);
+ bzero(req, full_size);
-extern int vbox_set_mouse(bool enable);
+ req->header.size = full_size;
+ req->header.version = VMMDEV_REQUEST_HEADER_VERSION;
+ req->header.requestType = VMMDevReq_SetPointerShape;
+ req->header.rc = -1;
-extern int vbox_get_mouse(bool *abs, uint16_t *xpos, uint16_t *ypos);
+ req->fFlags = VBOX_MOUSE_POINTER_SHAPE;
+ req->xHot = xHot;
+ req->yHot = yHot;
+ req->width = width;
+ req->height = height;
-// In CALLBACKS segment:
+ ffmemcpy(req->pointerData, data, data_size);
-extern int vbox_set_mouse_locked(bool enable);
+ vbox_send_request(vb->iobase, vb->buf_physaddr);
-extern int vbox_get_mouse_locked(bool *abs, uint16_t *xpos, uint16_t *ypos);
+ return req->header.rc;
+}
#endif