* Copyright 2005-2008, Axel DΓΆrfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include "accelerant_protos.h"
#include "accelerant.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <syslog.h>
#include <AutoDeleterOS.h>
#ifdef TRACE_ACCELERANT
extern "C" void _sPrintf(const char *format, ...);
# define TRACE(x) _sPrintf x
#else
# define TRACE(x) ;
#endif
struct accelerant_info *gInfo;
both, the first accelerant and all clones.
*/
static status_t
init_common(int device, bool isClone)
{
gInfo = (accelerant_info *)malloc(sizeof(accelerant_info));
MemoryDeleter infoDeleter(gInfo);
if (gInfo == NULL)
return B_NO_MEMORY;
memset(gInfo, 0, sizeof(accelerant_info));
gInfo->is_clone = isClone;
gInfo->device = device;
gInfo->current_mode = UINT16_MAX;
area_id sharedArea;
if (ioctl(device, VESA_GET_PRIVATE_DATA, &sharedArea, sizeof(area_id)) != 0)
return B_ERROR;
AreaDeleter sharedDeleter(clone_area("vesa shared info",
(void **)&gInfo->shared_info, B_ANY_ADDRESS,
B_READ_AREA | B_WRITE_AREA, sharedArea));
status_t status = gInfo->shared_info_area = sharedDeleter.Get();
if (status < B_OK)
return status;
gInfo->vesa_modes = (vesa_mode *)((uint8 *)gInfo->shared_info
+ gInfo->shared_info->vesa_mode_offset);
infoDeleter.Detach();
sharedDeleter.Detach();
return B_OK;
}
static void
uninit_common(void)
{
delete_area(gInfo->shared_info_area);
gInfo->shared_info_area = -1;
gInfo->shared_info = NULL;
if (gInfo->is_clone)
close(gInfo->device);
free(gInfo);
}
status_t
vesa_init_accelerant(int device)
{
TRACE(("vesa_init_accelerant()\n"));
status_t status = init_common(device, false);
if (status != B_OK)
return status;
status = create_mode_list();
if (status != B_OK) {
uninit_common();
return status;
}
vesa_propose_display_mode(&gInfo->shared_info->current_mode, NULL, NULL);
return B_OK;
}
ssize_t
vesa_accelerant_clone_info_size(void)
{
return B_PATH_NAME_LENGTH;
}
void
vesa_get_accelerant_clone_info(void *info)
{
ioctl(gInfo->device, VESA_GET_DEVICE_NAME, info, B_PATH_NAME_LENGTH);
}
status_t
vesa_clone_accelerant(void *info)
{
TRACE(("vesa_clone_accelerant()\n"));
char path[MAXPATHLEN];
strcpy(path, "/dev/");
strcat(path, (const char *)info);
int fd = open(path, B_READ_WRITE);
if (fd < 0)
return errno;
status_t status = init_common(fd, true);
if (status != B_OK)
goto err1;
status = gInfo->mode_list_area = clone_area(
"vesa cloned modes", (void **)&gInfo->mode_list,
B_ANY_ADDRESS, B_READ_AREA, gInfo->shared_info->mode_list_area);
if (status < B_OK)
goto err2;
return B_OK;
err2:
uninit_common();
err1:
close(fd);
return status;
}
its clones.
*/
void
vesa_uninit_accelerant(void)
{
TRACE(("vesa_uninit_accelerant()\n"));
delete_area(gInfo->mode_list_area);
gInfo->mode_list = NULL;
uninit_common();
}
status_t
vesa_get_accelerant_device_info(accelerant_device_info *info)
{
info->version = B_ACCELERANT_VERSION;
strcpy(info->name, "VESA driver");
if (gInfo->shared_info->name[0] != '\0') {
strlcpy(info->chipset, gInfo->shared_info->name, 32);
} else {
switch (gInfo->shared_info->bios_type) {
case kIntelBiosType:
strcpy(info->chipset, "Intel");
break;
case kNVidiaBiosType:
strcpy(info->chipset, "nVidia");
break;
case kAtomBiosType1:
case kAtomBiosType2:
strcpy(info->chipset, "AMD/ATI Atombios");
break;
default:
strcpy(info->chipset, "Generic VESA");
break;
}
}
strcpy(info->serial_no, "None");
info->memory = gInfo->shared_info->vram_size;
#if 0
info->dac_speed = ???
#endif
return B_OK;
}
sem_id
vesa_accelerant_retrace_semaphore()
{
return -1;
}