summaryrefslogtreecommitdiffstats
path: root/src/VBox/Additions/haiku/VBoxVideo
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/VBox/Additions/haiku/VBoxVideo/Makefile.kmk64
-rw-r--r--src/VBox/Additions/haiku/VBoxVideo/accelerant/Makefile.kmk75
-rw-r--r--src/VBox/Additions/haiku/VBoxVideo/accelerant/accelerant.cpp473
-rw-r--r--src/VBox/Additions/haiku/VBoxVideo/accelerant/accelerant.h115
-rw-r--r--src/VBox/Additions/haiku/VBoxVideo/common/VBoxVideo_common.h114
-rw-r--r--src/VBox/Additions/haiku/VBoxVideo/driver/Makefile.kmk95
-rw-r--r--src/VBox/Additions/haiku/VBoxVideo/driver/driver.cpp382
7 files changed, 1318 insertions, 0 deletions
diff --git a/src/VBox/Additions/haiku/VBoxVideo/Makefile.kmk b/src/VBox/Additions/haiku/VBoxVideo/Makefile.kmk
new file mode 100644
index 00000000..43090fec
--- /dev/null
+++ b/src/VBox/Additions/haiku/VBoxVideo/Makefile.kmk
@@ -0,0 +1,64 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-Makefile for Haiku VBoxVideo.
+#
+
+#
+# Copyright (C) 2012-2023 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-3.0-only
+#
+
+#
+# This code is based on:
+#
+# VirtualBox Guest Additions for Haiku.
+# Copyright (c) 2011 Mike Smith <mike@scgtrp.net>
+# François Revol <revol@free.fr>
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following
+# conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+
+SUB_DEPTH = ../../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+include $(PATH_SUB_CURRENT)/accelerant/Makefile.kmk
+include $(PATH_SUB_CURRENT)/driver/Makefile.kmk
+
+include $(KBUILD_PATH)/subfooter.kmk
+
diff --git a/src/VBox/Additions/haiku/VBoxVideo/accelerant/Makefile.kmk b/src/VBox/Additions/haiku/VBoxVideo/accelerant/Makefile.kmk
new file mode 100644
index 00000000..7084e0ed
--- /dev/null
+++ b/src/VBox/Additions/haiku/VBoxVideo/accelerant/Makefile.kmk
@@ -0,0 +1,75 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-Makefile for VBoxVideo accelerant, Haiku Guest Additions.
+#
+
+#
+# Copyright (C) 2012-2023 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-3.0-only
+#
+
+#
+# This code is based on:
+#
+# VirtualBox Guest Additions for Haiku.
+# Copyright (c) 2011 Mike Smith <mike@scgtrp.net>
+# François Revol <revol@free.fr>
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following
+# conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+
+SUB_DEPTH = ../../../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+PROGRAMS += vboxvideo.accelerant
+vboxvideo.accelerant_TEMPLATE = VBoxGuestR3Exe
+vboxvideo.accelerant_DEFS = VBOX_WITH_HGCM LOG_TO_BACKDOOR
+vboxvideo.accelerant_DEFS += LOG_ENABLED
+vboxvideo.accelerant_INCS = ../include
+vboxvideo.accelerant_SOURCES = \
+ accelerant.cpp
+
+vboxvideo.accelerant_LIBS = \
+ be device \
+ $(VBOX_LIB_IPRT_GUEST_R3_SHARED) \
+ $(VBOX_LIB_VBGL_R3) \
+ /system/servers/app_server
+
+include $(KBUILD_PATH)/subfooter.kmk
+
diff --git a/src/VBox/Additions/haiku/VBoxVideo/accelerant/accelerant.cpp b/src/VBox/Additions/haiku/VBoxVideo/accelerant/accelerant.cpp
new file mode 100644
index 00000000..5352bd82
--- /dev/null
+++ b/src/VBox/Additions/haiku/VBoxVideo/accelerant/accelerant.cpp
@@ -0,0 +1,473 @@
+/* $Id: accelerant.cpp $ */
+/** @file
+ * VBoxVideo Accelerant; Haiku Guest Additions, implementation.
+ */
+
+/*
+ * Copyright (C) 2012-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+/*
+ * This code is based on:
+ *
+ * VirtualBox Guest Additions for Haiku.
+ * Copyright (c) 2011 Mike Smith <mike@scgtrp.net>
+ * François Revol <revol@free.fr>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <Accelerant.h>
+#include "accelerant.h"
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+
+/*********************************************************************************************************************************
+* Global Variables *
+*********************************************************************************************************************************/
+AccelerantInfo gInfo;
+static engine_token sEngineToken = { 1, 0 /*B_2D_ACCELERATION*/, NULL };
+
+/** @todo r=ramshankar: get rid of this and replace with IPRT logging. */
+#define TRACE(x...) do { \
+ FILE* logfile = fopen("/var/log/vboxvideo.accelerant.log", "a"); \
+ fprintf(logfile, x); \
+ fflush(logfile); \
+ fsync(fileno(logfile)); \
+ fclose(logfile); \
+ sync(); \
+ } while(0)
+
+class AreaCloner
+{
+ public:
+ AreaCloner()
+ : fArea(-1)
+ {
+ }
+
+ ~AreaCloner()
+ {
+ if (fArea >= B_OK)
+ delete_area(fArea);
+ }
+
+ area_id Clone(const char *name, void **_address, uint32 spec, uint32 protection, area_id sourceArea)
+ {
+ fArea = clone_area(name, _address, spec, protection, sourceArea);
+ return fArea;
+ }
+
+ status_t InitCheck()
+ {
+ return fArea < B_OK ? (status_t)fArea : B_OK;
+ }
+
+ void Keep()
+ {
+ fArea = -1;
+ }
+
+ private:
+ area_id fArea;
+};
+
+extern "C"
+void* get_accelerant_hook(uint32 feature, void *data)
+{
+ TRACE("%s\n", __FUNCTION__);
+ switch (feature)
+ {
+ /* General */
+ case B_INIT_ACCELERANT:
+ return (void *)vboxvideo_init_accelerant;
+ case B_UNINIT_ACCELERANT:
+ return (void *)vboxvideo_uninit_accelerant;
+ case B_CLONE_ACCELERANT:
+ return (void *)vboxvideo_clone_accelerant;
+ case B_ACCELERANT_CLONE_INFO_SIZE:
+ return (void *)vboxvideo_accelerant_clone_info_size;
+ case B_GET_ACCELERANT_CLONE_INFO:
+ return (void *)vboxvideo_get_accelerant_clone_info;
+ case B_GET_ACCELERANT_DEVICE_INFO:
+ return (void *)vboxvideo_get_accelerant_device_info;
+ case B_ACCELERANT_RETRACE_SEMAPHORE:
+ return (void *)vboxvideo_accelerant_retrace_semaphore;
+
+ /* Mode configuration */
+ case B_ACCELERANT_MODE_COUNT:
+ return (void *)vboxvideo_accelerant_mode_count;
+ case B_GET_MODE_LIST:
+ return (void *)vboxvideo_get_mode_list;
+ case B_SET_DISPLAY_MODE:
+ return (void *)vboxvideo_set_display_mode;
+ case B_GET_DISPLAY_MODE:
+ return (void *)vboxvideo_get_display_mode;
+ case B_GET_EDID_INFO:
+ return (void *)vboxvideo_get_edid_info;
+ case B_GET_FRAME_BUFFER_CONFIG:
+ return (void *)vboxvideo_get_frame_buffer_config;
+ case B_GET_PIXEL_CLOCK_LIMITS:
+ return (void *)vboxvideo_get_pixel_clock_limits;
+
+#if 0
+ /* cursor managment */
+ case B_SET_CURSOR_SHAPE:
+ return (void*)vboxvideo_set_cursor_shape;
+ case B_MOVE_CURSOR:
+ return (void*)vboxvideo_move_cursor;
+ case B_SHOW_CURSOR:
+ return (void*)vboxvideo_show_cursor;
+#endif
+
+ /* Engine/synchronization */
+ case B_ACCELERANT_ENGINE_COUNT:
+ return (void *)vboxvideo_accelerant_engine_count;
+ case B_ACQUIRE_ENGINE:
+ return (void *)vboxvideo_acquire_engine;
+ case B_RELEASE_ENGINE:
+ return (void *)vboxvideo_release_engine;
+ case B_WAIT_ENGINE_IDLE:
+ return (void *)vboxvideo_wait_engine_idle;
+ case B_GET_SYNC_TOKEN:
+ return (void *)vboxvideo_get_sync_token;
+ case B_SYNC_TO_TOKEN:
+ return (void *)vboxvideo_sync_to_token;
+ }
+
+ return NULL;
+}
+
+status_t vboxvideo_init_common(int fd, bool cloned)
+{
+ unlink("/var/log/vboxvideo.accelerant.log"); // clear old log - next TRACE() will recreate it
+ TRACE("%s\n", __FUNCTION__);
+
+ gInfo.deviceFD = fd;
+ gInfo.isClone = cloned;
+ gInfo.sharedInfo = NULL;
+ gInfo.sharedInfoArea = -1;
+
+ area_id sharedArea;
+ if (ioctl(gInfo.deviceFD, VBOXVIDEO_GET_PRIVATE_DATA, &sharedArea, sizeof(area_id)) != 0)
+ {
+ TRACE("ioctl failed\n");
+ return B_ERROR;
+ }
+
+ AreaCloner sharedCloner;
+ gInfo.sharedInfoArea = sharedCloner.Clone("vboxvideo shared info", (void **)&gInfo.sharedInfo, B_ANY_ADDRESS,
+ B_READ_AREA | B_WRITE_AREA, sharedArea);
+ status_t status = sharedCloner.InitCheck();
+ if (status < B_OK)
+ {
+ TRACE("InitCheck failed (%s)\n", strerror(status));
+ return status;
+ }
+ sharedCloner.Keep();
+
+ return B_OK;
+}
+
+
+status_t vboxvideo_init_accelerant(int fd)
+{
+ return vboxvideo_init_common(fd, false);
+}
+
+
+ssize_t vboxvideo_accelerant_clone_info_size(void)
+{
+ TRACE("%s\n", __FUNCTION__);
+ return B_PATH_NAME_LENGTH;
+}
+
+
+void vboxvideo_get_accelerant_clone_info(void *data)
+{
+ TRACE("%s\n", __FUNCTION__);
+ ioctl(gInfo.deviceFD, VBOXVIDEO_GET_DEVICE_NAME, data, B_PATH_NAME_LENGTH);
+}
+
+
+status_t vboxvideo_clone_accelerant(void *data)
+{
+ TRACE("%s\n", __FUNCTION__);
+
+ /* Create full device name */
+ char path[MAXPATHLEN];
+ strcpy(path, "/dev/");
+ strcat(path, (const char *)data);
+
+ int fd = open(path, B_READ_WRITE);
+ if (fd < 0)
+ return errno;
+
+ return vboxvideo_init_common(fd, true);
+}
+
+
+void vboxvideo_uninit_accelerant(void)
+{
+ delete_area(gInfo.sharedInfoArea);
+ gInfo.sharedInfo = NULL;
+ gInfo.sharedInfoArea = -1;
+
+ if (gInfo.isClone)
+ close(gInfo.deviceFD);
+
+ TRACE("%s\n", __FUNCTION__);
+}
+
+
+status_t vboxvideo_get_accelerant_device_info(accelerant_device_info *adi)
+{
+ TRACE("%s\n", __FUNCTION__);
+ adi->version = B_ACCELERANT_VERSION;
+ strcpy(adi->name, "Virtual display");
+ strcpy(adi->chipset, "VirtualBox Graphics Adapter");
+ strcpy(adi->serial_no, "9001");
+ return B_OK;
+}
+
+
+sem_id vboxvideo_accelerant_retrace_semaphore(void)
+{
+ TRACE("%s\n", __FUNCTION__);
+ return -1;
+}
+
+
+// modes & constraints
+uint32 vboxvideo_accelerant_mode_count(void)
+{
+ TRACE("%s\n", __FUNCTION__);
+ return 1;
+}
+
+
+status_t vboxvideo_get_mode_list(display_mode *dm)
+{
+ /// @todo return some standard modes here
+ TRACE("%s\n", __FUNCTION__);
+ return vboxvideo_get_display_mode(dm);
+}
+
+
+status_t vboxvideo_set_display_mode(display_mode *modeToSet)
+{
+ TRACE("%s\n", __FUNCTION__);
+ TRACE("trying to set mode %dx%d\n", modeToSet->timing.h_display, modeToSet->timing.v_display);
+ return ioctl(gInfo.deviceFD, VBOXVIDEO_SET_DISPLAY_MODE, modeToSet, sizeof(display_mode));
+}
+
+
+status_t vboxvideo_get_display_mode(display_mode *currentMode)
+{
+ TRACE("%s\n", __FUNCTION__);
+ *currentMode = gInfo.sharedInfo->currentMode;
+ TRACE("current mode is %dx%d\n", currentMode->timing.h_display, currentMode->timing.v_display);
+ return B_OK;
+}
+
+
+status_t vboxvideo_get_edid_info(void *info, size_t size, uint32 *_version)
+{
+ TRACE("%s\n", __FUNCTION__);
+
+ /* Copied from the X11 implementation: */
+ static const uint8 edid_data[128] = {
+ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, /* header */
+ 0x58, 0x58, /* manufacturer (VBX) */
+ 0x00, 0x00, /* product code */
+ 0x00, 0x00, 0x00, 0x00, /* serial number goes here */
+ 0x01, /* week of manufacture */
+ 0x00, /* year of manufacture */
+ 0x01, 0x03, /* EDID version */
+ 0x80, /* capabilities - digital */
+ 0x00, /* horiz. res in cm, zero for projectors */
+ 0x00, /* vert. res in cm */
+ 0x78, /* display gamma (120 == 2.2). Should we ask the host for this? */
+ 0xEE, /* features (standby, suspend, off, RGB, standard colour space,
+ * preferred timing mode) */
+ 0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F, 0x50, 0x54,
+ /* chromaticity for standard colour space - should we ask the host? */
+ 0x00, 0x00, 0x00, /* no default timings */
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, /* no standard timings */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* descriptor block 1 goes here */
+ 0x00, 0x00, 0x00, 0xFD, 0x00, /* descriptor block 2, monitor ranges */
+ 0x00, 0xC8, 0x00, 0xC8, 0x64, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, /* 0-200Hz vertical, 0-200KHz horizontal, 1000MHz pixel clock */
+ 0x00, 0x00, 0x00, 0xFC, 0x00, /* descriptor block 3, monitor name */
+ 'V', 'B', 'O', 'X', ' ', 'm', 'o', 'n', 'i', 't', 'o', 'r', '\n',
+ 0x00, 0x00, 0x00, 0x10, 0x00, /* descriptor block 4: dummy data */
+ 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20,
+ 0x00, /* number of extensions */
+ 0x00 /* checksum goes here */
+ };
+
+ if (size < 128)
+ return B_BUFFER_OVERFLOW;
+
+ *_version = 1; /* EDID_VERSION_1 */
+ memcpy(info, edid_data, 128);
+ return B_OK;
+}
+
+
+status_t vboxvideo_get_frame_buffer_config(frame_buffer_config *config)
+{
+ TRACE("%s\n", __FUNCTION__);
+ config->frame_buffer = gInfo.sharedInfo->framebuffer;
+ config->frame_buffer_dma = NULL;
+ config->bytes_per_row = get_depth_for_color_space(gInfo.sharedInfo->currentMode.space)
+ * gInfo.sharedInfo->currentMode.timing.h_display / 8;
+ return B_OK;
+}
+
+
+status_t vboxvideo_get_pixel_clock_limits(display_mode *dm, uint32 *low, uint32 *high)
+{
+ TRACE("%s\n", __FUNCTION__);
+ // irrelevant for virtual monitors
+ *low = 0;
+ *high = 9001;
+ return B_OK;
+}
+
+
+/* Cursor */
+status_t vboxvideo_set_cursor_shape(uint16 width, uint16 height, uint16 hotX, uint16 hotY, uint8 *andMask, uint8 *xorMask)
+{
+ TRACE("%s\n", __FUNCTION__);
+ // VBoxHGSMIUpdatePointerShape
+ return B_UNSUPPORTED;
+}
+
+
+void vboxvideo_move_cursor(uint16 x, uint16 y)
+{
+ TRACE("%s\n", __FUNCTION__);
+}
+
+
+void vboxvideo_show_cursor(bool is_visible)
+{
+ TRACE("%s\n", __FUNCTION__);
+}
+
+
+/* Accelerant engine */
+uint32 vboxvideo_accelerant_engine_count(void)
+{
+ TRACE("%s\n", __FUNCTION__);
+ return 1;
+}
+
+status_t vboxvideo_acquire_engine(uint32 capabilities, uint32 maxWait, sync_token *st, engine_token **et)
+{
+ TRACE("%s\n", __FUNCTION__);
+ *et = &sEngineToken;
+ return B_OK;
+}
+
+
+status_t vboxvideo_release_engine(engine_token *et, sync_token *st)
+{
+ TRACE("%s\n", __FUNCTION__);
+ if (st != NULL)
+ st->engine_id = et->engine_id;
+
+ return B_OK;
+}
+
+
+void vboxvideo_wait_engine_idle(void)
+{
+ TRACE("%s\n", __FUNCTION__);
+}
+
+
+status_t vboxvideo_get_sync_token(engine_token *et, sync_token *st)
+{
+ TRACE("%s\n", __FUNCTION__);
+ return B_OK;
+}
+
+
+status_t vboxvideo_sync_to_token(sync_token *st)
+{
+ TRACE("%s\n", __FUNCTION__);
+ return B_OK;
+}
+
+
+/* 2D acceleration */
+void vboxvideo_screen_to_screen_blit(engine_token *et, blit_params *list, uint32 count)
+{
+ TRACE("%s\n", __FUNCTION__);
+}
+
+
+void vboxvideo_fill_rectangle(engine_token *et, uint32 color, fill_rect_params *list, uint32 count)
+{
+ TRACE("%s\n", __FUNCTION__);
+}
+
+
+void vboxvideo_invert_rectangle(engine_token *et, fill_rect_params *list, uint32 count)
+{
+ TRACE("%s\n", __FUNCTION__);
+}
+
+
+void vboxvideo_fill_span(engine_token *et, uint32 color, uint16 *list, uint32 count)
+{
+ TRACE("%s\n", __FUNCTION__);
+}
diff --git a/src/VBox/Additions/haiku/VBoxVideo/accelerant/accelerant.h b/src/VBox/Additions/haiku/VBoxVideo/accelerant/accelerant.h
new file mode 100644
index 00000000..735f4d2b
--- /dev/null
+++ b/src/VBox/Additions/haiku/VBoxVideo/accelerant/accelerant.h
@@ -0,0 +1,115 @@
+/* $Id: accelerant.h $ */
+/** @file
+ * VBoxVideo Accelerant; Haiku Guest Additions, header.
+ */
+
+/*
+ * Copyright (C) 2012-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+/*
+ * This code is based on:
+ *
+ * VirtualBox Guest Additions for Haiku.
+ * Copyright (c) 2011 Mike Smith <mike@scgtrp.net>
+ * François Revol <revol@free.fr>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef GA_INCLUDED_SRC_haiku_VBoxVideo_accelerant_accelerant_h
+#define GA_INCLUDED_SRC_haiku_VBoxVideo_accelerant_accelerant_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <Accelerant.h>
+#include "../common/VBoxVideo_common.h"
+
+struct AccelerantInfo
+{
+ /** @todo doxygen document these fields */
+ int deviceFD;
+ bool isClone;
+
+ SharedInfo *sharedInfo;
+ area_id sharedInfoArea;
+};
+extern AccelerantInfo gInfo;
+
+/* General */
+status_t vboxvideo_init_accelerant(int fd);
+ssize_t vboxvideo_accelerant_clone_info_size(void);
+void vboxvideo_get_accelerant_clone_info(void *data);
+status_t vboxvideo_clone_accelerant(void *data);
+void vboxvideo_uninit_accelerant(void);
+status_t vboxvideo_get_accelerant_device_info(accelerant_device_info *adi);
+sem_id vboxvideo_accelerant_retrace_semaphore(void);
+
+/* Modes & constraints */
+uint32 vboxvideo_accelerant_mode_count(void);
+status_t vboxvideo_get_mode_list(display_mode *dm);
+status_t vboxvideo_set_display_mode(display_mode *modeToSet);
+status_t vboxvideo_get_display_mode(display_mode *currentMode);
+status_t vboxvideo_get_edid_info(void *info, size_t size, uint32 *_version);
+status_t vboxvideo_get_frame_buffer_config(frame_buffer_config *config);
+status_t vboxvideo_get_pixel_clock_limits(display_mode *dm, uint32 *low, uint32 *high);
+
+/* Cursor */
+status_t vboxvideo_set_cursor_shape(uint16 width, uint16 height, uint16 hotX, uint16 hotY, uint8 *andMask, uint8 *xorMask);
+void vboxvideo_move_cursor(uint16 x, uint16 y);
+void vboxvideo_show_cursor(bool is_visible);
+
+/* Accelerant engine */
+uint32 vboxvideo_accelerant_engine_count(void);
+status_t vboxvideo_acquire_engine(uint32 capabilities, uint32 maxWait, sync_token *st, engine_token **et);
+status_t vboxvideo_release_engine(engine_token *et, sync_token *st);
+void vboxvideo_wait_engine_idle(void);
+status_t vboxvideo_get_sync_token(engine_token *et, sync_token *st);
+status_t vboxvideo_sync_to_token(sync_token *st);
+
+/* 2D acceleration */
+void vboxvideo_screen_to_screen_blit(engine_token *et, blit_params *list, uint32 count);
+void vboxvideo_fill_rectangle(engine_token *et, uint32 color, fill_rect_params *list, uint32 count);
+void vboxvideo_invert_rectangle(engine_token *et, fill_rect_params *list, uint32 count);
+void vboxvideo_fill_span(engine_token *et, uint32 color, uint16 *list, uint32 count);
+
+#endif /* !GA_INCLUDED_SRC_haiku_VBoxVideo_accelerant_accelerant_h */
+
diff --git a/src/VBox/Additions/haiku/VBoxVideo/common/VBoxVideo_common.h b/src/VBox/Additions/haiku/VBoxVideo/common/VBoxVideo_common.h
new file mode 100644
index 00000000..b00bce3f
--- /dev/null
+++ b/src/VBox/Additions/haiku/VBoxVideo/common/VBoxVideo_common.h
@@ -0,0 +1,114 @@
+/* $Id: VBoxVideo_common.h $ */
+/** @file
+ * VBoxVideo, Haiku Guest Additions, common header.
+ */
+
+/*
+ * Copyright (C) 2012-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+/*
+ * This code is based on:
+ *
+ * VirtualBox Guest Additions for Haiku.
+ * Copyright (c) 2011 Mike Smith <mike@scgtrp.net>
+ * François Revol <revol@free.fr>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef GA_INCLUDED_SRC_haiku_VBoxVideo_common_VBoxVideo_common_h
+#define GA_INCLUDED_SRC_haiku_VBoxVideo_common_VBoxVideo_common_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <Drivers.h>
+#include <Accelerant.h>
+#include <PCI.h>
+
+struct SharedInfo
+{
+ display_mode currentMode;
+ area_id framebufferArea;
+ void *framebuffer;
+};
+
+enum
+{
+ VBOXVIDEO_GET_PRIVATE_DATA = B_DEVICE_OP_CODES_END + 1,
+ VBOXVIDEO_GET_DEVICE_NAME,
+ VBOXVIDEO_SET_DISPLAY_MODE
+};
+
+static inline uint32 get_color_space_for_depth(uint32 depth)
+{
+ switch (depth)
+ {
+ case 1: return B_GRAY1;
+ case 4: return B_GRAY8;
+ /* The app_server is smart enough to translate this to VGA mode */
+ case 8: return B_CMAP8;
+ case 15: return B_RGB15;
+ case 16: return B_RGB16;
+ case 24: return B_RGB24;
+ case 32: return B_RGB32;
+ }
+
+ return 0;
+}
+
+static inline uint32 get_depth_for_color_space(uint32 depth)
+{
+ switch (depth)
+ {
+ case B_GRAY1: return 1;
+ case B_GRAY8: return 4;
+ case B_CMAP8: return 8;
+ case B_RGB15: return 15;
+ case B_RGB16: return 16;
+ case B_RGB24: return 24;
+ case B_RGB32: return 32;
+ }
+ return 0;
+}
+
+#endif /* !GA_INCLUDED_SRC_haiku_VBoxVideo_common_VBoxVideo_common_h */
+
diff --git a/src/VBox/Additions/haiku/VBoxVideo/driver/Makefile.kmk b/src/VBox/Additions/haiku/VBoxVideo/driver/Makefile.kmk
new file mode 100644
index 00000000..b32a91b3
--- /dev/null
+++ b/src/VBox/Additions/haiku/VBoxVideo/driver/Makefile.kmk
@@ -0,0 +1,95 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-Makefile for VBoxVideo driver, Haiku Guest Additions.
+#
+
+#
+# Copyright (C) 2012-2023 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-3.0-only
+#
+
+#
+# This code is based on:
+#
+# VirtualBox Guest Additions for Haiku.
+# Copyright (c) 2011 Mike Smith <mike@scgtrp.net>
+# François Revol <revol@free.fr>
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following
+# conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+
+SUB_DEPTH = ../../../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+ifdef VBOX_WITH_ADDITION_DRIVERS
+ SYSMODS += vboxvideo
+endif
+
+#
+# Populate FILES_VBOXSF_NOBIN
+#
+#include $(PATH_SUB_CURRENT)/files_VBoxVideo
+
+#
+# The module (for syntax checking).
+# The DEBUG_HASH* stuff is for CONFIG_DYNAMIC_DEBUG-enabled kernels
+#
+vboxvideo_TEMPLATE = VBoxGuestR0Drv
+vboxvideo_DEFS = \
+ MODULE IN_RT_R0 VBOXGUEST VBOX_WITH_HGCM \
+ KBUILD_MODNAME=KBUILD_STR\(VBoxVideo\) \
+ KBUILD_BASENAME=KBUILD_STR\(VBoxVideo\)
+vboxvideo_INCS = \
+ $(PATH_ROOT)/src/VBox/Additions/common/VBoxGuestLib \
+ $(PATH_ROOT)/src/VBox/Additions/common/VBoxGuest \
+ $(PATH_ROOT)/src/VBox/Runtime/r0drv/haiku \
+ $(VBOX_GRAPHICS_INCS)
+vboxvideo_SOURCES = \
+ driver.cpp \
+ $(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp \
+ $(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/HGSMIBuffers.cpp \
+ $(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp \
+ $(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/VBVABase.cpp \
+ $(PATH_ROOT)/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku-stubs.c
+vboxvideo_LIBS = \
+ $(VBOX_LIB_VBGL_R0) \
+ $(VBOX_PATH_ADDITIONS_LIB)/HGSMIGuestR0Lib$(VBOX_SUFF_LIB)
+
+include $(KBUILD_PATH)/subfooter.kmk
+
diff --git a/src/VBox/Additions/haiku/VBoxVideo/driver/driver.cpp b/src/VBox/Additions/haiku/VBoxVideo/driver/driver.cpp
new file mode 100644
index 00000000..ce04560a
--- /dev/null
+++ b/src/VBox/Additions/haiku/VBoxVideo/driver/driver.cpp
@@ -0,0 +1,382 @@
+/* $Id: driver.cpp $ */
+/** @file
+ * VBoxVideo driver, Haiku Guest Additions, implementation.
+ */
+
+/*
+ * Copyright (C) 2012-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+/*
+ * This code is based on:
+ *
+ * VirtualBox Guest Additions for Haiku.
+ * Copyright (c) 2011 Mike Smith <mike@scgtrp.net>
+ * François Revol <revol@free.fr>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <KernelExport.h>
+#include <PCI.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
+#include <graphic_driver.h>
+#include <VBoxGuest-haiku.h>
+#include <VBoxVideoGuest.h>
+#include "../common/VBoxVideo_common.h"
+
+#define VENDOR_ID 0x80ee
+#define DEVICE_ID 0xbeef
+#define DRIVER_NAME "VBoxVideoDriver"
+#define DEVICE_FORMAT "vd_%04X_%04X_%02X%02X%02X"
+
+/** @todo r=ramshankar: pretty sure IPRT has something for page rounding,
+ * replace with IPRT version later. */
+#define ROUND_TO_PAGE_SIZE(x) (((x) + (B_PAGE_SIZE) - 1) & ~((B_PAGE_SIZE) - 1))
+
+#define ENABLE_DEBUG_TRACE
+
+#undef TRACE
+#ifdef ENABLE_DEBUG_TRACE
+#define TRACE(x...) dprintf("VBoxVideo: " x)
+#else
+#define TRACE(x...) ;
+#endif
+
+int32 api_version = B_CUR_DRIVER_API_VERSION; // revision of driver API we support
+
+extern "C" status_t vm_set_area_memory_type(area_id id, phys_addr_t physicalBase, uint32 type);
+
+struct Benaphore
+{
+ sem_id sem;
+ int32 count;
+
+ status_t Init(const char *name)
+ {
+ count = 0;
+ sem = create_sem(0, name);
+ return sem < 0 ? sem : B_OK;
+ }
+
+ status_t Acquire()
+ {
+ if (atomic_add(&count, 1) > 0)
+ return acquire_sem(sem);
+ return B_OK;
+ }
+
+ status_t Release()
+ {
+ if (atomic_add(&count, -1) > 1)
+ return release_sem(sem);
+ return B_OK;
+ }
+
+ void Delete()
+ {
+ delete_sem(sem);
+ }
+};
+
+struct DeviceInfo
+{
+ uint32 openCount; /* Count of how many times device has been opened */
+ uint32 flags; /* Device flags */
+ area_id sharedArea; /* Area shared between driver and all accelerants */
+ SharedInfo *sharedInfo; /* Pointer to shared info area memory */
+ pci_info pciInfo; /* Copy of pci info for this device */
+ char name[B_OS_NAME_LENGTH]; /* Name of device */
+};
+
+
+/*********************************************************************************************************************************
+* Internal Functions *
+*********************************************************************************************************************************/
+status_t device_open(const char *name, uint32 flags, void **cookie);
+status_t device_close(void *dev);
+status_t device_free(void *dev);
+status_t device_read(void *dev, off_t pos, void *buf, size_t *len);
+status_t device_write(void *dev, off_t pos, const void *buf, size_t *len);
+status_t device_ioctl(void *dev, uint32 msg, void *buf, size_t len);
+static uint32 get_color_space_for_depth(uint32 depth);
+
+
+/*********************************************************************************************************************************
+* Globals *
+*********************************************************************************************************************************/
+/* At most one virtual video card ever appears, no reason for this to be an array */
+static DeviceInfo gDeviceInfo;
+static char *gDeviceNames[2] = { gDeviceInfo.name, NULL };
+static bool gCanHasDevice = false; /* is the device present? */
+static Benaphore gLock;
+static pci_module_info *gPCI;
+
+static device_hooks gDeviceHooks =
+{
+ device_open,
+ device_close,
+ device_free,
+ device_ioctl,
+ device_read,
+ device_write,
+ NULL, /* select */
+ NULL, /* deselect */
+ NULL, /* read_pages */
+ NULL /* write_pages */
+};
+
+
+status_t init_hardware()
+{
+ LogFlowFunc(("init_hardware\n"));
+
+ status_t err = get_module(VBOXGUEST_MODULE_NAME, (module_info **)&g_VBoxGuest);
+ if (err == B_OK)
+ {
+ err = get_module(B_PCI_MODULE_NAME, (module_info **)&gPCI);
+ if (err == B_OK)
+ return B_OK;
+
+ LogRel((DRIVER_NAME ":_init_hardware() get_module(%s) failed. err=%08lx\n", B_PCI_MODULE_NAME));
+ }
+ else
+ LogRel((DRIVER_NAME ":_init_hardware() get_module(%s) failed. err=%08lx\n", VBOXGUEST_MODULE_NAME, err));
+ return B_ERROR;
+}
+
+
+status_t init_driver()
+{
+ LogFlowFunc(("init_driver\n"));
+
+ gLock.Init("VBoxVideo driver lock");
+
+ uint32 pciIndex = 0;
+
+ while (gPCI->get_nth_pci_info(pciIndex, &gDeviceInfo.pciInfo) == B_OK)
+ {
+ if (gDeviceInfo.pciInfo.vendor_id == VENDOR_ID && gDeviceInfo.pciInfo.device_id == DEVICE_ID)
+ {
+ sprintf(gDeviceInfo.name, "graphics/" DEVICE_FORMAT,
+ gDeviceInfo.pciInfo.vendor_id, gDeviceInfo.pciInfo.device_id,
+ gDeviceInfo.pciInfo.bus, gDeviceInfo.pciInfo.device, gDeviceInfo.pciInfo.function);
+ TRACE("found device %s\n", gDeviceInfo.name);
+
+ gCanHasDevice = true;
+ gDeviceInfo.openCount = 0;
+
+ size_t sharedSize = (sizeof(SharedInfo) + 7) & ~7;
+ gDeviceInfo.sharedArea = create_area("vboxvideo shared info",
+ (void **)&gDeviceInfo.sharedInfo, B_ANY_KERNEL_ADDRESS,
+ ROUND_TO_PAGE_SIZE(sharedSize), B_FULL_LOCK,
+ B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_USER_CLONEABLE_AREA);
+
+ uint16_t width, height, vwidth, bpp, flags;
+ VBoxVideoGetModeRegisters(&width, &height, &vwidth, &bpp, &flags);
+
+ gDeviceInfo.sharedInfo->currentMode.space = get_color_space_for_depth(bpp);
+ gDeviceInfo.sharedInfo->currentMode.virtual_width = width;
+ gDeviceInfo.sharedInfo->currentMode.virtual_height = height;
+ gDeviceInfo.sharedInfo->currentMode.h_display_start = 0;
+ gDeviceInfo.sharedInfo->currentMode.v_display_start = 0;
+ gDeviceInfo.sharedInfo->currentMode.flags = 0;
+ gDeviceInfo.sharedInfo->currentMode.timing.h_display = width;
+ gDeviceInfo.sharedInfo->currentMode.timing.v_display = height;
+ /* Not used, but this makes a reasonable-sounding refresh rate show in screen prefs: */
+ gDeviceInfo.sharedInfo->currentMode.timing.h_total = 1000;
+ gDeviceInfo.sharedInfo->currentMode.timing.v_total = 1;
+ gDeviceInfo.sharedInfo->currentMode.timing.pixel_clock = 850;
+
+ /* Map the PCI memory space */
+ uint32 command_reg = gPCI->read_pci_config(gDeviceInfo.pciInfo.bus,
+ gDeviceInfo.pciInfo.device, gDeviceInfo.pciInfo.function, PCI_command, 2);
+ command_reg |= PCI_command_io | PCI_command_memory | PCI_command_master;
+ gPCI->write_pci_config(gDeviceInfo.pciInfo.bus, gDeviceInfo.pciInfo.device,
+ gDeviceInfo.pciInfo.function, PCI_command, 2, command_reg);
+
+ gDeviceInfo.sharedInfo->framebufferArea = map_physical_memory("vboxvideo framebuffer",
+ (phys_addr_t)gDeviceInfo.pciInfo.u.h0.base_registers[0],
+ gDeviceInfo.pciInfo.u.h0.base_register_sizes[0], B_ANY_KERNEL_BLOCK_ADDRESS,
+ B_READ_AREA | B_WRITE_AREA, &(gDeviceInfo.sharedInfo->framebuffer));
+ vm_set_area_memory_type(gDeviceInfo.sharedInfo->framebufferArea,
+ (phys_addr_t)gDeviceInfo.pciInfo.u.h0.base_registers[0], B_MTR_WC);
+ break;
+ }
+
+ pciIndex++;
+ }
+
+ return B_OK;
+}
+
+
+const char** publish_devices()
+{
+ LogFlowFunc(("publish_devices\n"));
+ if (gCanHasDevice)
+ return (const char **)gDeviceNames;
+ return NULL;
+}
+
+
+device_hooks* find_device(const char *name)
+{
+ LogFlowFunc(("find_device\n"));
+ if (gCanHasDevice && strcmp(name, gDeviceInfo.name) == 0)
+ return &gDeviceHooks;
+
+ return NULL;
+}
+
+
+void uninit_driver()
+{
+ LogFlowFunc(("uninit_driver\n"));
+ gLock.Delete();
+ put_module(VBOXGUEST_MODULE_NAME);
+}
+
+status_t device_open(const char *name, uint32 flags, void **cookie)
+{
+ LogFlowFunc(("device_open\n"));
+
+ if (!gCanHasDevice || strcmp(name, gDeviceInfo.name) != 0)
+ return B_BAD_VALUE;
+
+ /** @todo init device! */
+
+ *cookie = (void *)&gDeviceInfo;
+ return B_OK;
+}
+
+
+status_t device_close(void *dev)
+{
+ LogFlowFunc(("device_close\n"));
+ return B_ERROR;
+}
+
+
+status_t device_free(void *dev)
+{
+ LogFlowFunc(("device_free\n"));
+
+ DeviceInfo& di = *(DeviceInfo *)dev;
+ gLock.Acquire();
+
+ if (di.openCount <= 1)
+ {
+ /// @todo deinit device!
+ delete_area(di.sharedArea);
+ di.sharedArea = -1;
+ di.sharedInfo = NULL;
+ }
+
+ if (di.openCount > 0)
+ di.openCount--;
+
+ gLock.Release();
+
+ return B_OK;
+}
+
+
+status_t device_read(void *dev, off_t pos, void *buf, size_t *len)
+{
+ LogFlowFunc(("device_read\n"));
+ return B_NOT_ALLOWED;
+}
+
+
+status_t device_write(void *dev, off_t pos, const void *buf, size_t *len)
+{
+ LogFlowFunc(("device_write\n"));
+ return B_NOT_ALLOWED;
+}
+
+
+status_t device_ioctl(void *cookie, uint32 msg, void *buf, size_t len)
+{
+ LogFlowFunc(("device_ioctl\n"));
+
+ DeviceInfo *dev = (DeviceInfo *)cookie;
+
+ switch (msg)
+ {
+ case B_GET_ACCELERANT_SIGNATURE:
+ {
+ strcpy((char *)buf, "vboxvideo.accelerant");
+ return B_OK;
+ }
+
+ case VBOXVIDEO_GET_PRIVATE_DATA:
+ {
+ /** @todo r=ramshankar: implement RTR0MemUserCopyFrom for haiku. */
+ return user_memcpy(buf, &dev->sharedArea, sizeof(area_id));
+ }
+
+ case VBOXVIDEO_GET_DEVICE_NAME:
+ {
+ /** @todo r=ramshankar: implement RTR0MemUserCopyFrom for haiku. */
+ if (user_strlcpy((char *)buf, gDeviceInfo.name, len) < B_OK)
+ return B_BAD_ADDRESS;
+ return B_OK;
+ }
+
+ case VBOXVIDEO_SET_DISPLAY_MODE:
+ {
+ display_mode *mode = (display_mode *)buf;
+ VBoxVideoSetModeRegisters(mode->timing.h_display, mode->timing.v_display,
+ mode->timing.h_display, get_depth_for_color_space(mode->space), 0, 0, 0);
+ gDeviceInfo.sharedInfo->currentMode = *mode;
+ return B_OK;
+ }
+ default:
+ return B_BAD_VALUE;
+ }
+}
+