VirtualBox

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

Last change on this file since 69496 was 69496, checked in by vboxsync, 7 years ago

*: scm --update-copyright-year

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