VirtualBox

source: vbox/trunk/src/VBox/Additions/haiku/VBoxVideo/accelerant/accelerant.cpp@ 107044

Last change on this file since 107044 was 106061, checked in by vboxsync, 3 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.9 KB
Line 
1/* $Id: accelerant.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * VBoxVideo Accelerant; Haiku Guest Additions, implementation.
4 */
5
6/*
7 * Copyright (C) 2012-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/*
29 * This code is based on:
30 *
31 * VirtualBox Guest Additions for Haiku.
32 * Copyright (c) 2011 Mike Smith <mike@scgtrp.net>
33 * François Revol <revol@free.fr>
34 *
35 * Permission is hereby granted, free of charge, to any person
36 * obtaining a copy of this software and associated documentation
37 * files (the "Software"), to deal in the Software without
38 * restriction, including without limitation the rights to use,
39 * copy, modify, merge, publish, distribute, sublicense, and/or sell
40 * copies of the Software, and to permit persons to whom the
41 * Software is furnished to do so, subject to the following
42 * conditions:
43 *
44 * The above copyright notice and this permission notice shall be
45 * included in all copies or substantial portions of the Software.
46 *
47 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
48 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
49 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
50 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
51 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
52 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
53 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
54 * OTHER DEALINGS IN THE SOFTWARE.
55 */
56
57
58/*********************************************************************************************************************************
59* Header Files *
60*********************************************************************************************************************************/
61#include <Accelerant.h>
62#include "accelerant.h"
63#include <stdio.h>
64#include <string.h>
65#include <errno.h>
66
67
68/*********************************************************************************************************************************
69* Global Variables *
70*********************************************************************************************************************************/
71AccelerantInfo gInfo;
72static engine_token sEngineToken = { 1, 0 /*B_2D_ACCELERATION*/, NULL };
73
74/** @todo r=ramshankar: get rid of this and replace with IPRT logging. */
75#define TRACE(x...) do { \
76 FILE* logfile = fopen("/var/log/vboxvideo.accelerant.log", "a"); \
77 fprintf(logfile, x); \
78 fflush(logfile); \
79 fsync(fileno(logfile)); \
80 fclose(logfile); \
81 sync(); \
82 } while(0)
83
84class AreaCloner
85{
86 public:
87 AreaCloner()
88 : fArea(-1)
89 {
90 }
91
92 ~AreaCloner()
93 {
94 if (fArea >= B_OK)
95 delete_area(fArea);
96 }
97
98 area_id Clone(const char *name, void **_address, uint32 spec, uint32 protection, area_id sourceArea)
99 {
100 fArea = clone_area(name, _address, spec, protection, sourceArea);
101 return fArea;
102 }
103
104 status_t InitCheck()
105 {
106 return fArea < B_OK ? (status_t)fArea : B_OK;
107 }
108
109 void Keep()
110 {
111 fArea = -1;
112 }
113
114 private:
115 area_id fArea;
116};
117
118extern "C"
119void* get_accelerant_hook(uint32 feature, void *data)
120{
121 TRACE("%s\n", __FUNCTION__);
122 switch (feature)
123 {
124 /* General */
125 case B_INIT_ACCELERANT:
126 return (void *)vboxvideo_init_accelerant;
127 case B_UNINIT_ACCELERANT:
128 return (void *)vboxvideo_uninit_accelerant;
129 case B_CLONE_ACCELERANT:
130 return (void *)vboxvideo_clone_accelerant;
131 case B_ACCELERANT_CLONE_INFO_SIZE:
132 return (void *)vboxvideo_accelerant_clone_info_size;
133 case B_GET_ACCELERANT_CLONE_INFO:
134 return (void *)vboxvideo_get_accelerant_clone_info;
135 case B_GET_ACCELERANT_DEVICE_INFO:
136 return (void *)vboxvideo_get_accelerant_device_info;
137 case B_ACCELERANT_RETRACE_SEMAPHORE:
138 return (void *)vboxvideo_accelerant_retrace_semaphore;
139
140 /* Mode configuration */
141 case B_ACCELERANT_MODE_COUNT:
142 return (void *)vboxvideo_accelerant_mode_count;
143 case B_GET_MODE_LIST:
144 return (void *)vboxvideo_get_mode_list;
145 case B_SET_DISPLAY_MODE:
146 return (void *)vboxvideo_set_display_mode;
147 case B_GET_DISPLAY_MODE:
148 return (void *)vboxvideo_get_display_mode;
149 case B_GET_EDID_INFO:
150 return (void *)vboxvideo_get_edid_info;
151 case B_GET_FRAME_BUFFER_CONFIG:
152 return (void *)vboxvideo_get_frame_buffer_config;
153 case B_GET_PIXEL_CLOCK_LIMITS:
154 return (void *)vboxvideo_get_pixel_clock_limits;
155
156#if 0
157 /* cursor managment */
158 case B_SET_CURSOR_SHAPE:
159 return (void*)vboxvideo_set_cursor_shape;
160 case B_MOVE_CURSOR:
161 return (void*)vboxvideo_move_cursor;
162 case B_SHOW_CURSOR:
163 return (void*)vboxvideo_show_cursor;
164#endif
165
166 /* Engine/synchronization */
167 case B_ACCELERANT_ENGINE_COUNT:
168 return (void *)vboxvideo_accelerant_engine_count;
169 case B_ACQUIRE_ENGINE:
170 return (void *)vboxvideo_acquire_engine;
171 case B_RELEASE_ENGINE:
172 return (void *)vboxvideo_release_engine;
173 case B_WAIT_ENGINE_IDLE:
174 return (void *)vboxvideo_wait_engine_idle;
175 case B_GET_SYNC_TOKEN:
176 return (void *)vboxvideo_get_sync_token;
177 case B_SYNC_TO_TOKEN:
178 return (void *)vboxvideo_sync_to_token;
179 }
180
181 return NULL;
182}
183
184status_t vboxvideo_init_common(int fd, bool cloned)
185{
186 unlink("/var/log/vboxvideo.accelerant.log"); // clear old log - next TRACE() will recreate it
187 TRACE("%s\n", __FUNCTION__);
188
189 gInfo.deviceFD = fd;
190 gInfo.isClone = cloned;
191 gInfo.sharedInfo = NULL;
192 gInfo.sharedInfoArea = -1;
193
194 area_id sharedArea;
195 if (ioctl(gInfo.deviceFD, VBOXVIDEO_GET_PRIVATE_DATA, &sharedArea, sizeof(area_id)) != 0)
196 {
197 TRACE("ioctl failed\n");
198 return B_ERROR;
199 }
200
201 AreaCloner sharedCloner;
202 gInfo.sharedInfoArea = sharedCloner.Clone("vboxvideo shared info", (void **)&gInfo.sharedInfo, B_ANY_ADDRESS,
203 B_READ_AREA | B_WRITE_AREA, sharedArea);
204 status_t status = sharedCloner.InitCheck();
205 if (status < B_OK)
206 {
207 TRACE("InitCheck failed (%s)\n", strerror(status));
208 return status;
209 }
210 sharedCloner.Keep();
211
212 return B_OK;
213}
214
215
216status_t vboxvideo_init_accelerant(int fd)
217{
218 return vboxvideo_init_common(fd, false);
219}
220
221
222ssize_t vboxvideo_accelerant_clone_info_size(void)
223{
224 TRACE("%s\n", __FUNCTION__);
225 return B_PATH_NAME_LENGTH;
226}
227
228
229void vboxvideo_get_accelerant_clone_info(void *data)
230{
231 TRACE("%s\n", __FUNCTION__);
232 ioctl(gInfo.deviceFD, VBOXVIDEO_GET_DEVICE_NAME, data, B_PATH_NAME_LENGTH);
233}
234
235
236status_t vboxvideo_clone_accelerant(void *data)
237{
238 TRACE("%s\n", __FUNCTION__);
239
240 /* Create full device name */
241 char path[MAXPATHLEN];
242 strcpy(path, "/dev/");
243 strcat(path, (const char *)data);
244
245 int fd = open(path, B_READ_WRITE);
246 if (fd < 0)
247 return errno;
248
249 return vboxvideo_init_common(fd, true);
250}
251
252
253void vboxvideo_uninit_accelerant(void)
254{
255 delete_area(gInfo.sharedInfoArea);
256 gInfo.sharedInfo = NULL;
257 gInfo.sharedInfoArea = -1;
258
259 if (gInfo.isClone)
260 close(gInfo.deviceFD);
261
262 TRACE("%s\n", __FUNCTION__);
263}
264
265
266status_t vboxvideo_get_accelerant_device_info(accelerant_device_info *adi)
267{
268 TRACE("%s\n", __FUNCTION__);
269 adi->version = B_ACCELERANT_VERSION;
270 strcpy(adi->name, "Virtual display");
271 strcpy(adi->chipset, "VirtualBox Graphics Adapter");
272 strcpy(adi->serial_no, "9001");
273 return B_OK;
274}
275
276
277sem_id vboxvideo_accelerant_retrace_semaphore(void)
278{
279 TRACE("%s\n", __FUNCTION__);
280 return -1;
281}
282
283
284// modes & constraints
285uint32 vboxvideo_accelerant_mode_count(void)
286{
287 TRACE("%s\n", __FUNCTION__);
288 return 1;
289}
290
291
292status_t vboxvideo_get_mode_list(display_mode *dm)
293{
294 /// @todo return some standard modes here
295 TRACE("%s\n", __FUNCTION__);
296 return vboxvideo_get_display_mode(dm);
297}
298
299
300status_t vboxvideo_set_display_mode(display_mode *modeToSet)
301{
302 TRACE("%s\n", __FUNCTION__);
303 TRACE("trying to set mode %dx%d\n", modeToSet->timing.h_display, modeToSet->timing.v_display);
304 return ioctl(gInfo.deviceFD, VBOXVIDEO_SET_DISPLAY_MODE, modeToSet, sizeof(display_mode));
305}
306
307
308status_t vboxvideo_get_display_mode(display_mode *currentMode)
309{
310 TRACE("%s\n", __FUNCTION__);
311 *currentMode = gInfo.sharedInfo->currentMode;
312 TRACE("current mode is %dx%d\n", currentMode->timing.h_display, currentMode->timing.v_display);
313 return B_OK;
314}
315
316
317status_t vboxvideo_get_edid_info(void *info, size_t size, uint32 *_version)
318{
319 TRACE("%s\n", __FUNCTION__);
320
321 /* Copied from the X11 implementation: */
322 static const uint8 edid_data[128] = {
323 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, /* header */
324 0x58, 0x58, /* manufacturer (VBX) */
325 0x00, 0x00, /* product code */
326 0x00, 0x00, 0x00, 0x00, /* serial number goes here */
327 0x01, /* week of manufacture */
328 0x00, /* year of manufacture */
329 0x01, 0x03, /* EDID version */
330 0x80, /* capabilities - digital */
331 0x00, /* horiz. res in cm, zero for projectors */
332 0x00, /* vert. res in cm */
333 0x78, /* display gamma (120 == 2.2). Should we ask the host for this? */
334 0xEE, /* features (standby, suspend, off, RGB, standard colour space,
335 * preferred timing mode) */
336 0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F, 0x50, 0x54,
337 /* chromaticity for standard colour space - should we ask the host? */
338 0x00, 0x00, 0x00, /* no default timings */
339 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
340 0x01, 0x01, 0x01, 0x01, /* no standard timings */
341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* descriptor block 1 goes here */
343 0x00, 0x00, 0x00, 0xFD, 0x00, /* descriptor block 2, monitor ranges */
344 0x00, 0xC8, 0x00, 0xC8, 0x64, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
345 0x20, /* 0-200Hz vertical, 0-200KHz horizontal, 1000MHz pixel clock */
346 0x00, 0x00, 0x00, 0xFC, 0x00, /* descriptor block 3, monitor name */
347 'V', 'B', 'O', 'X', ' ', 'm', 'o', 'n', 'i', 't', 'o', 'r', '\n',
348 0x00, 0x00, 0x00, 0x10, 0x00, /* descriptor block 4: dummy data */
349 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
350 0x20,
351 0x00, /* number of extensions */
352 0x00 /* checksum goes here */
353 };
354
355 if (size < 128)
356 return B_BUFFER_OVERFLOW;
357
358 *_version = 1; /* EDID_VERSION_1 */
359 memcpy(info, edid_data, 128);
360 return B_OK;
361}
362
363
364status_t vboxvideo_get_frame_buffer_config(frame_buffer_config *config)
365{
366 TRACE("%s\n", __FUNCTION__);
367 config->frame_buffer = gInfo.sharedInfo->framebuffer;
368 config->frame_buffer_dma = NULL;
369 config->bytes_per_row = get_depth_for_color_space(gInfo.sharedInfo->currentMode.space)
370 * gInfo.sharedInfo->currentMode.timing.h_display / 8;
371 return B_OK;
372}
373
374
375status_t vboxvideo_get_pixel_clock_limits(display_mode *dm, uint32 *low, uint32 *high)
376{
377 TRACE("%s\n", __FUNCTION__);
378 // irrelevant for virtual monitors
379 *low = 0;
380 *high = 9001;
381 return B_OK;
382}
383
384
385/* Cursor */
386status_t vboxvideo_set_cursor_shape(uint16 width, uint16 height, uint16 hotX, uint16 hotY, uint8 *andMask, uint8 *xorMask)
387{
388 TRACE("%s\n", __FUNCTION__);
389 // VBoxHGSMIUpdatePointerShape
390 return B_UNSUPPORTED;
391}
392
393
394void vboxvideo_move_cursor(uint16 x, uint16 y)
395{
396 TRACE("%s\n", __FUNCTION__);
397}
398
399
400void vboxvideo_show_cursor(bool is_visible)
401{
402 TRACE("%s\n", __FUNCTION__);
403}
404
405
406/* Accelerant engine */
407uint32 vboxvideo_accelerant_engine_count(void)
408{
409 TRACE("%s\n", __FUNCTION__);
410 return 1;
411}
412
413status_t vboxvideo_acquire_engine(uint32 capabilities, uint32 maxWait, sync_token *st, engine_token **et)
414{
415 TRACE("%s\n", __FUNCTION__);
416 *et = &sEngineToken;
417 return B_OK;
418}
419
420
421status_t vboxvideo_release_engine(engine_token *et, sync_token *st)
422{
423 TRACE("%s\n", __FUNCTION__);
424 if (st != NULL)
425 st->engine_id = et->engine_id;
426
427 return B_OK;
428}
429
430
431void vboxvideo_wait_engine_idle(void)
432{
433 TRACE("%s\n", __FUNCTION__);
434}
435
436
437status_t vboxvideo_get_sync_token(engine_token *et, sync_token *st)
438{
439 TRACE("%s\n", __FUNCTION__);
440 return B_OK;
441}
442
443
444status_t vboxvideo_sync_to_token(sync_token *st)
445{
446 TRACE("%s\n", __FUNCTION__);
447 return B_OK;
448}
449
450
451/* 2D acceleration */
452void vboxvideo_screen_to_screen_blit(engine_token *et, blit_params *list, uint32 count)
453{
454 TRACE("%s\n", __FUNCTION__);
455}
456
457
458void vboxvideo_fill_rectangle(engine_token *et, uint32 color, fill_rect_params *list, uint32 count)
459{
460 TRACE("%s\n", __FUNCTION__);
461}
462
463
464void vboxvideo_invert_rectangle(engine_token *et, fill_rect_params *list, uint32 count)
465{
466 TRACE("%s\n", __FUNCTION__);
467}
468
469
470void vboxvideo_fill_span(engine_token *et, uint32 color, uint16 *list, uint32 count)
471{
472 TRACE("%s\n", __FUNCTION__);
473}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette