libwayland: disable wayland-scanner (host build fix); libdrm: remove orphaned fork cache (v6.0 2026)

Two related cleanups for the libdrm Rule 2 migration (commit 5f5eec1c4):

  * libwayland: add -Dscanner=false to cookbook_meson, with a 20-line
    comment explaining the rationale. Without this flag, libwayland's
    meson.build builds a `wayland-scanner` executable for the *target*
    (Redox). The resulting binary has /lib/ld64.so.1 as its ELF
    interpreter (Redox's loader) and is useless on the build host. The
    pkgconfig that libwayland installs (wayland-scanner.pc) then points
    `wayland_scanner` to this Redox binary, and downstream consumers
    (mesa, wayland-protocols) pick it up via
    dependency('wayland-scanner'). When the cookbook's redoxer sandbox
    tries to exec it on the host, the host kernel can't find
    /lib/ld64.so.1 and the build fails with 'required file not found'.

    Disabling the scanner means libwayland doesn't install
    wayland-scanner to the sysroot. Downstream consumers then fall
    through to the host's /usr/bin/wayland-scanner (a proper
    x86_64-linux-gnu binary that works on the build host). This
    matches what wayland-protocols already does in its own meson.build
    (see its redox.patch in the recipe).

  * libdrm: remove 4 orphaned source-cache files that were left over
    from the libdrm Local source fork at local/sources/libdrm/ (deleted
    in commit 5f5eec1c4). The 4 files were the in-tree Red Bear edits
    that are now external patches in local/patches/libdrm/:

      - source/virtgpu_drm.h       DELETED (was in 01-drm-ioctl-bridge.patch)
      - source/xf86drm.c           MODIFIED (most edits moved to patch)
      - source/xf86drmMode.c       MODIFIED (most edits moved to patch)
      - source/xf86drm_redox.h     DELETED (was in 01-drm-ioctl-bridge.patch)

    The local/recipes/libs/libdrm/source/ cache is now empty (only
    upstream files) and is regenerated by 'repo cook' from the upstream
    git URL specified in the recipe. These 4 files are no longer
    touched by the build system.

Fixes the build correctness issue where downstream mesa/wayland-protocols
builds would fail with 'required file not found: /lib/ld64.so.1' due to
wayland-scanner being built for the wrong target. The fix mirrors what
upstream Redox's wayland-protocols recipe does in its own meson.build.
This commit is contained in:
2026-06-10 01:45:14 +03:00
parent b0f440c47e
commit 90a264f1b1
5 changed files with 26 additions and 1468 deletions
@@ -1,132 +0,0 @@
#ifndef _VIRTGPU_DRM_H_
#define _VIRTGPU_DRM_H_
#include <stdint.h>
#define DRM_VIRTGPU_MAP 0x41
#define DRM_VIRTGPU_EXECBUFFER 0x42
#define DRM_VIRTGPU_GETPARAM 0x43
#define DRM_VIRTGPU_RESOURCE_CREATE 0x44
#define DRM_VIRTGPU_RESOURCE_INFO 0x45
#define DRM_VIRTGPU_TRANSFER_FROM_HOST 0x46
#define DRM_VIRTGPU_TRANSFER_TO_HOST 0x47
#define DRM_VIRTGPU_WAIT 0x48
#define DRM_VIRTGPU_GET_CAPS 0x49
#define DRM_VIRTGPU_RESOURCE_CREATE_BLOB 0x4A
#define DRM_VIRTGPU_CONTEXT_INIT 0x4B
#define drm_virtgpu_resource_create drm_virtgpu_resource_create_3d
#define drm_virtgpu_3d_transfer_to_host drm_virtgpu_transfer_to_host
#define drm_virtgpu_3d_transfer_from_host drm_virtgpu_transfer_from_host
#define drm_virtgpu_3d_wait drm_virtgpu_wait_3d
#define ctx_set_params_ptr ctx_set_params
#define resource_id res_handle
struct drm_virtgpu_3d_box {
uint32_t x;
uint32_t y;
uint32_t z;
uint32_t w;
uint32_t h;
uint32_t d;
};
struct drm_virtgpu_execbuffer {
uint32_t flags;
uint32_t size;
uint64_t command;
uint64_t bo_handles;
uint32_t num_bo_handles;
int32_t fence_fd;
uint32_t ring_idx;
uint32_t syncobj_stride;
uint32_t num_in_syncobjs;
uint32_t num_out_syncobjs;
uint64_t in_syncobjs;
uint64_t out_syncobjs;
};
struct drm_virtgpu_getparam {
uint64_t param;
uint64_t value;
};
struct drm_virtgpu_resource_create_3d {
uint32_t target;
uint32_t format;
uint32_t bind;
uint32_t width;
uint32_t height;
uint32_t depth;
uint32_t array_size;
uint32_t last_level;
uint32_t nr_samples;
uint32_t flags;
uint32_t bo_handle;
uint32_t res_handle;
uint32_t size;
uint32_t stride;
};
struct drm_virtgpu_resource_info {
uint32_t bo_handle;
uint32_t res_handle;
uint32_t size;
uint32_t blob_mem;
};
struct drm_virtgpu_transfer_to_host {
uint32_t bo_handle;
struct drm_virtgpu_3d_box box;
uint32_t level;
uint32_t offset;
uint32_t stride;
uint32_t layer_stride;
};
struct drm_virtgpu_transfer_from_host {
uint32_t bo_handle;
struct drm_virtgpu_3d_box box;
uint32_t level;
uint32_t offset;
uint32_t stride;
uint32_t layer_stride;
};
struct drm_virtgpu_wait_3d {
uint32_t handle;
uint32_t flags;
};
struct drm_virtgpu_get_caps {
uint32_t cap_set_id;
uint32_t cap_set_ver;
uint64_t addr;
uint32_t size;
uint32_t pad;
};
struct drm_virtgpu_resource_create_blob {
uint32_t blob_mem;
uint32_t blob_flags;
uint32_t bo_handle;
uint32_t res_handle;
uint64_t size;
uint32_t pad;
uint32_t cmd_size;
uint64_t cmd;
uint64_t blob_id;
};
struct drm_virtgpu_context_set_param {
uint64_t param;
uint64_t value;
};
struct drm_virtgpu_context_init {
uint32_t num_params;
uint32_t pad;
uint64_t ctx_set_params;
};
#endif
+5 -598
View File
@@ -88,10 +88,8 @@
#endif
#include "xf86drm.h"
#include "xf86drm_redox.h"
#include "libdrm_macros.h"
#include "drm_fourcc.h"
#include "virtgpu_drm.h"
#include "util_math.h"
@@ -115,7 +113,7 @@
#define DRM_MAJOR 226 /* Linux */
#endif
#if defined(__OpenBSD__) || defined(__DragonFly__) || defined(__redox__)
#if defined(__OpenBSD__) || defined(__DragonFly__)
struct drm_pciinfo {
uint16_t domain;
uint8_t bus;
@@ -315,6 +313,7 @@ drmGetFormatModifierNameFromArm(uint64_t modifier)
uint64_t type = (modifier >> 52) & 0xf;
FILE *fp;
size_t size = 0;
char *modifier_name = NULL;
bool result = false;
@@ -322,7 +321,6 @@ drmGetFormatModifierNameFromArm(uint64_t modifier)
fprintf(stderr, "open_memstream not available on Redox\n");
return NULL;
#else
size_t size = 0;
fp = open_memstream(&modifier_name, &size);
if (!fp)
return NULL;
@@ -427,12 +425,12 @@ drmGetFormatModifierNameFromAmd(uint64_t modifier)
uint64_t tile_version = AMD_FMT_MOD_GET(TILE_VERSION, modifier);
FILE *fp;
char *mod_amd = NULL;
size_t size = 0;
#if defined(__redox__)
fprintf(stderr, "open_memstream not available on Redox\n");
return NULL;
#else
size_t size = 0;
fp = open_memstream(&mod_amd, &size);
if (!fp)
return NULL;
@@ -705,366 +703,18 @@ drm_public void drmFree(void *pt)
free(pt);
}
#if defined(__redox__)
static int redox_drm_write_all(int fd, const void *buf, size_t len)
{
const uint8_t *bytes = buf;
size_t offset = 0;
while (offset < len) {
ssize_t written = write(fd, bytes + offset, len - offset);
if (written < 0) {
if (errno == EINTR || errno == EAGAIN)
continue;
return -1;
}
if (written == 0) {
errno = EIO;
return -1;
}
offset += (size_t)written;
}
return 0;
}
static int redox_drm_read_all(int fd, void *buf, size_t len)
{
uint8_t *bytes = buf;
size_t offset = 0;
while (offset < len) {
ssize_t read_count = read(fd, bytes + offset, len - offset);
if (read_count < 0) {
if (errno == EINTR || errno == EAGAIN)
continue;
return -1;
}
if (read_count == 0) {
errno = EIO;
return -1;
}
offset += (size_t)read_count;
}
return 0;
}
static int redox_drm_send_request(int fd, unsigned long request_code,
const void *payload, size_t payload_size)
{
const size_t request_word_size = sizeof(uintptr_t);
const size_t total_size = request_word_size + payload_size;
uint8_t stack_request[sizeof(uintptr_t)];
uint8_t *request_bytes = stack_request;
uintptr_t request_word = (uintptr_t)request_code;
size_t i;
if (total_size > sizeof(stack_request)) {
request_bytes = drmMalloc(total_size);
if (!request_bytes) {
errno = ENOMEM;
return -1;
}
}
for (i = 0; i < request_word_size; ++i)
request_bytes[i] = (uint8_t)((request_word >> (i * 8)) & 0xffU);
if (payload_size != 0)
memcpy(request_bytes + request_word_size, payload, payload_size);
if (redox_drm_write_all(fd, request_bytes, total_size) != 0) {
if (request_bytes != stack_request)
drmFree(request_bytes);
return -1;
}
if (request_bytes != stack_request)
drmFree(request_bytes);
return 0;
}
static int redox_drm_get_response_size(int fd, size_t *response_size)
{
stat_t st;
if (fstat(fd, &st) != 0)
return -1;
*response_size = (size_t)st.st_size;
return 0;
}
unsigned long redox_translate_request(unsigned long linux_nr)
{
switch (linux_nr) {
case 0x0C:
return REDOX_DRM_IOCTL_GET_CAP;
case 0x0D:
return REDOX_DRM_IOCTL_SET_CLIENT_CAP;
case 0x09:
return REDOX_DRM_IOCTL_GEM_CLOSE;
case 0xA6:
return REDOX_DRM_IOCTL_MODE_GETENCODER;
case 0xB3:
return REDOX_DRM_IOCTL_MODE_MAP_DUMB;
case 0xB4:
return REDOX_DRM_IOCTL_MODE_DESTROY_DUMB;
case 0xAF:
return REDOX_DRM_IOCTL_MODE_RMFB;
/* VirtGPU ioctls (NR 0x41-0x4B) */
case 0x41:
return REDOX_DRM_IOCTL_VIRTGPU_MAP;
case 0x42:
return REDOX_DRM_IOCTL_VIRTGPU_EXECBUFFER;
case 0x43:
return REDOX_DRM_IOCTL_VIRTGPU_GETPARAM;
case 0x44:
return REDOX_DRM_IOCTL_VIRTGPU_RESOURCE_CREATE;
case 0x45:
return REDOX_DRM_IOCTL_VIRTGPU_RESOURCE_INFO;
case 0x46:
return REDOX_DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST;
case 0x47:
return REDOX_DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST;
case 0x48:
return REDOX_DRM_IOCTL_VIRTGPU_WAIT;
case 0x49:
return REDOX_DRM_IOCTL_VIRTGPU_GET_CAPS;
case 0x4A:
return REDOX_DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB;
case 0x4B:
return REDOX_DRM_IOCTL_VIRTGPU_CONTEXT_INIT;
/* Additional standard DRM ioctls */
case 0x00:
return REDOX_DRM_IOCTL_VERSION;
case 0xA0:
return REDOX_DRM_IOCTL_MODE_GETRESOURCES;
case 0xA1:
return REDOX_DRM_IOCTL_MODE_GETCRTC;
case 0xA2:
return REDOX_DRM_IOCTL_MODE_SETCRTC;
case 0xA3:
return REDOX_DRM_IOCTL_MODE_GETCONNECTOR;
case 0xA4:
return REDOX_DRM_IOCTL_MODE_PAGE_FLIP;
case 0xA8:
return REDOX_DRM_IOCTL_MODE_CREATE_DUMB;
case 0xAC:
return REDOX_DRM_IOCTL_MODE_ADDFB;
case 0x2B:
return REDOX_DRM_IOCTL_PRIME_HANDLE_TO_FD;
case 0x2C:
return REDOX_DRM_IOCTL_PRIME_FD_TO_HANDLE;
/* DRM_IOCTL_GET_PCIINFO — PCI device information for driver discovery */
case 0x15:
return REDOX_DRM_IOCTL_GET_PCI_INFO;
/* DRM auth/master ioctls */
case 0x02: /* GET_MAGIC — DRM_IOR(0x02, struct drm_auth) */
return REDOX_DRM_IOCTL_GET_MAGIC;
case 0x11: /* AUTH_MAGIC — DRM_IOW(0x11, struct drm_auth) */
return REDOX_DRM_IOCTL_AUTH_MAGIC;
case 0x1e: /* SET_MASTER — DRM_IO(0x1e) */
return REDOX_DRM_IOCTL_SET_MASTER;
case 0x1f: /* DROP_MASTER — DRM_IO(0x1f) */
return REDOX_DRM_IOCTL_DROP_MASTER;
default:
return 0;
}
}
int redox_drm_exchange(int fd, unsigned long request_code,
const void *payload, size_t payload_size,
void *response, size_t response_capacity,
size_t *response_size)
{
uint8_t stack_buffer[64];
uint8_t *response_buffer = stack_buffer;
size_t actual_response_size = 0;
if (redox_drm_send_request(fd, request_code, payload, payload_size) != 0)
return -1;
if (redox_drm_get_response_size(fd, &actual_response_size) != 0)
return -1;
if (response_size)
*response_size = actual_response_size;
if (actual_response_size == 0)
return 0;
if (response && response_capacity >= actual_response_size) {
return redox_drm_read_all(fd, response, actual_response_size);
}
if (actual_response_size > sizeof(stack_buffer)) {
response_buffer = drmMalloc(actual_response_size);
if (!response_buffer) {
errno = ENOMEM;
return -1;
}
}
if (redox_drm_read_all(fd, response_buffer, actual_response_size) != 0) {
if (response_buffer != stack_buffer)
drmFree(response_buffer);
return -1;
}
if (response_buffer != stack_buffer)
drmFree(response_buffer);
if (response && response_capacity < actual_response_size) {
errno = EMSGSIZE;
return -1;
}
return 0;
}
int redox_drm_exchange_alloc(int fd, unsigned long request_code,
const void *payload, size_t payload_size,
void **response, size_t *response_size)
{
size_t actual_response_size = 0;
void *allocated_response = NULL;
if (!response) {
errno = EINVAL;
return -1;
}
if (redox_drm_send_request(fd, request_code, payload, payload_size) != 0)
return -1;
if (redox_drm_get_response_size(fd, &actual_response_size) != 0)
return -1;
if (actual_response_size != 0) {
allocated_response = drmMalloc(actual_response_size);
if (!allocated_response) {
errno = ENOMEM;
return -1;
}
if (redox_drm_read_all(fd, allocated_response, actual_response_size) != 0) {
drmFree(allocated_response);
return -1;
}
}
*response = allocated_response;
if (response_size)
*response_size = actual_response_size;
return 0;
}
static size_t redox_drm_expected_response_size(unsigned long linux_nr, size_t arg_size)
{
switch (linux_nr) {
case 0x00: /* VERSION */
case 0x0C:
case 0x2B: /* PRIME_HANDLE_TO_FD */
case 0x2C: /* PRIME_FD_TO_HANDLE */
case 0x41: /* VIRTGPU_MAP */
case 0x43: /* VIRTGPU_GETPARAM */
case 0x44: /* VIRTGPU_RESOURCE_CREATE */
case 0x45: /* VIRTGPU_RESOURCE_INFO */
case 0xA0: /* MODE_GETRESOURCES */
case 0xA1: /* MODE_GETCRTC */
case 0xA3: /* MODE_GETCONNECTOR */
case 0xA8: /* MODE_CREATE_DUMB */
case 0xAC: /* MODE_ADDFB */
case 0xA6:
case 0xB3:
return arg_size;
case 0x02: /* GET_MAGIC — returns struct drm_auth (magic u32) */
return arg_size;
case 0x11: /* AUTH_MAGIC — returns struct drm_auth (magic u32) */
return arg_size;
default:
return 0;
}
}
int redox_drm_simple_ioctl(int fd, unsigned long request, void *arg)
{
const unsigned long linux_nr = REDOX_LINUX_IOCTL_NR(request);
const unsigned long request_code = redox_translate_request(linux_nr);
const size_t arg_size = REDOX_LINUX_IOCTL_SIZE(request);
const size_t expected_response_size = redox_drm_expected_response_size(linux_nr, arg_size);
if (request_code == 0) {
errno = ENOTTY;
return -1;
}
if (linux_nr == 0x42) { /* VIRTGPU_EXECBUFFER */
struct drm_virtgpu_execbuffer *eb = arg;
size_t total = arg_size + eb->size;
uint8_t *buf = drmMalloc((int)total);
int ret;
if (!buf)
return -1;
memcpy(buf, arg, arg_size);
if (eb->size > 0 && eb->command)
memcpy(buf + arg_size, (void *)(uintptr_t)eb->command, eb->size);
ret = redox_drm_exchange(fd, request_code, buf, total, NULL, 0, NULL);
drmFree(buf);
return ret;
}
if (linux_nr == 0x49) { /* VIRTGPU_GET_CAPS */
struct drm_virtgpu_get_caps *gc = arg;
void *resp;
size_t resp_size;
int ret;
ret = redox_drm_exchange_alloc(fd, request_code, arg, arg_size, &resp, &resp_size);
if (ret == 0 && resp && resp_size > 0) {
size_t copy = resp_size < gc->size ? resp_size : gc->size;
memcpy((void *)(uintptr_t)gc->addr, resp, copy);
drmFree(resp);
}
return ret;
}
if (redox_drm_exchange(fd, request_code,
arg, arg ? arg_size : 0,
expected_response_size ? arg : NULL,
expected_response_size,
NULL) != 0) {
return -1;
}
return 0;
}
#endif
/**
* Call ioctl, restarting if it is interrupted
*/
drm_public int
drmIoctl(int fd, unsigned long request, void *arg)
{
#if defined(__redox__)
return redox_drm_simple_ioctl(fd, request, arg);
#else
int ret;
do {
ret = ioctl(fd, request, arg);
} while (ret == -1 && (errno == EINTR || errno == EAGAIN));
return ret;
#endif
}
static unsigned long drmGetKeyFromFd(int fd)
@@ -1443,7 +1093,6 @@ static int drmGetMinorType(int major, int minor)
return -1;
}
#if !defined(__redox__)
static const char *drmGetMinorName(int type)
{
switch (type) {
@@ -1455,7 +1104,6 @@ static const char *drmGetMinorName(int type)
return NULL;
}
}
#endif
/**
* Open the device by bus ID.
@@ -1553,11 +1201,7 @@ static int drmOpenByName(const char *name, int type)
for (i = base; i < base + DRM_MAX_MINOR; i++) {
if ((fd = drmOpenMinor(i, 1, type)) >= 0) {
if ((version = drmGetVersion(fd))) {
#if defined(__redox__)
if (!version->name || !strcmp(version->name, name)) {
#else
if (!strcmp(version->name, name)) {
#endif
drmFreeVersion(version);
id = drmGetBusid(fd);
drmMsg("drmGetBusid returned '%s'\n", id ? id : "NULL");
@@ -1710,7 +1354,6 @@ drm_public void drmFreeVersion(drmVersionPtr v)
* Used by drmGetVersion() to free the memory pointed by \p %v as well as all
* the non-null strings pointers in it.
*/
#if !defined(__redox__)
static void drmFreeKernelVersion(drm_version_t *v)
{
if (!v)
@@ -1720,7 +1363,6 @@ static void drmFreeKernelVersion(drm_version_t *v)
drmFree(v->desc);
drmFree(v);
}
#endif
/**
@@ -1733,7 +1375,6 @@ static void drmFreeKernelVersion(drm_version_t *v)
* Used by drmGetVersion() to translate the information returned by the ioctl
* interface in a private structure into the public structure counterpart.
*/
#if !defined(__redox__)
static void drmCopyVersion(drmVersionPtr d, const drm_version_t *s)
{
d->version_major = s->version_major;
@@ -1746,7 +1387,6 @@ static void drmCopyVersion(drmVersionPtr d, const drm_version_t *s)
d->desc_len = s->desc_len;
d->desc = s->desc ? strdup(s->desc) : NULL;
}
#endif
/**
@@ -1766,50 +1406,6 @@ static void drmCopyVersion(drmVersionPtr d, const drm_version_t *s)
*/
drm_public drmVersionPtr drmGetVersion(int fd)
{
#if defined(__redox__)
drmVersionPtr retval = drmMalloc(sizeof(*retval));
struct redox_drm_version_wire version;
if (!retval)
return NULL;
if (redox_drm_exchange(fd, REDOX_DRM_IOCTL_VERSION,
NULL, 0,
&version, sizeof(version),
NULL) != 0) {
drmFree(retval);
return NULL;
}
memclear(*retval);
retval->version_major = version.major;
retval->version_minor = version.minor;
retval->version_patchlevel = version.patch;
/* The scheme returns a NUL-terminated driver name in version.name.
* KWin drm_gpu.cpp dereferences version->name unconditionally
* (strstr checks for "i915", "amdgpu", "virtio" etc.) so it must
* never be NULL.
*/
version.name[sizeof(version.name) - 1] = '\0';
if (version.name[0] != '\0') {
size_t len = strlen(version.name);
retval->name = drmMalloc(len + 1);
if (retval->name) {
memcpy(retval->name, version.name, len + 1);
retval->name_len = len;
}
} else {
const char fallback[] = "redox-drm";
retval->name = drmMalloc(sizeof(fallback));
if (retval->name) {
memcpy(retval->name, fallback, sizeof(fallback));
retval->name_len = sizeof(fallback) - 1;
}
}
return retval;
#else
drmVersionPtr retval;
drm_version_t *version = drmMalloc(sizeof(*version));
@@ -1840,7 +1436,6 @@ drm_public drmVersionPtr drmGetVersion(int fd)
drmCopyVersion(retval, version);
drmFreeKernelVersion(version);
return retval;
#endif
}
@@ -3805,23 +3400,6 @@ drm_public int drmGetNodeTypeFromFd(int fd)
drm_public int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags,
int *prime_fd)
{
#if defined(__redox__)
struct redox_drm_prime_handle_to_fd_wire request;
struct redox_drm_prime_handle_to_fd_response_wire response;
memclear(request);
request.handle = handle;
request.flags = flags;
if (redox_drm_exchange(fd, REDOX_DRM_IOCTL_PRIME_HANDLE_TO_FD,
&request, sizeof(request),
&response, sizeof(response),
NULL) != 0) {
return -errno;
}
*prime_fd = response.fd;
return 0;
#else
struct drm_prime_handle args;
int ret;
@@ -3835,27 +3413,10 @@ drm_public int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags,
*prime_fd = args.fd;
return 0;
#endif
}
drm_public int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle)
{
#if defined(__redox__)
struct redox_drm_prime_fd_to_handle_wire request;
struct redox_drm_prime_fd_to_handle_response_wire response;
memclear(request);
request.fd = prime_fd;
if (redox_drm_exchange(fd, REDOX_DRM_IOCTL_PRIME_FD_TO_HANDLE,
&request, sizeof(request),
&response, sizeof(response),
NULL) != 0) {
return -errno;
}
*handle = response.handle;
return 0;
#else
struct drm_prime_handle args;
int ret;
@@ -3867,7 +3428,6 @@ drm_public int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle)
*handle = args.handle;
return 0;
#endif
}
drm_public int drmCloseBufferHandle(int fd, uint32_t handle)
@@ -3984,7 +3544,7 @@ static char *drmGetMinorNameForFD(int fd, int type)
n = drmGetNodePath(buf, sizeof(buf), type, min);
if (n < 0)
return NULL;
if ((size_t)n >= sizeof(buf))
if (n == -1 || n >= sizeof(buf))
return NULL;
return strdup(buf);
@@ -4106,7 +3666,7 @@ static int drmParseSubsystemType(int maj, int min)
return DRM_BUS_VIRTIO;
}
return subsystem_type;
#elif defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__redox__)
#elif defined(__OpenBSD__) || defined(__DragonFly__) || defined(__FreeBSD__)
return DRM_BUS_PCI;
#else
#warning "Missing implementation of drmParseSubsystemType"
@@ -4240,21 +3800,6 @@ static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info)
return 0;
#elif defined(__FreeBSD__)
return get_sysctl_pci_bus_info(maj, min, info);
#elif defined(__redox__)
int rfd = open("/scheme/drm/card0", O_RDONLY);
if (rfd < 0)
return -errno;
uint8_t buf[22];
size_t rsize = 0;
int ret = redox_drm_exchange(rfd, REDOX_DRM_IOCTL_GET_PCI_INFO, NULL, 0, buf, sizeof(buf), &rsize);
close(rfd);
if (ret != 0 || rsize < 17)
return -EIO;
info->domain = buf[10] | (buf[11] << 8) | (buf[12] << 16) | (buf[13] << 24);
info->bus = buf[14];
info->dev = buf[15];
info->func = buf[16];
return 0;
#else
#warning "Missing implementation of drmParsePciBusInfo"
return -EINVAL;
@@ -4464,23 +4009,6 @@ static int drmParsePciDeviceInfo(int maj, int min,
device->revision_id = results[0].pc_revid;
return 0;
#elif defined(__redox__)
int rfd2 = open("/scheme/drm/card0", O_RDONLY);
if (rfd2 < 0)
return -errno;
uint8_t dbuf[22];
size_t drsize = 0;
int dret = redox_drm_exchange(rfd2, REDOX_DRM_IOCTL_GET_PCI_INFO, NULL, 0, dbuf, sizeof(dbuf), &drsize);
close(rfd2);
if (dret != 0 || drsize < 9)
return -EIO;
device->vendor_id = dbuf[0] | (dbuf[1] << 8);
device->device_id = dbuf[2] | (dbuf[3] << 8);
device->subvendor_id = dbuf[4] | (dbuf[5] << 8);
device->subdevice_id = dbuf[6] | (dbuf[7] << 8);
if (drsize >= 9)
device->revision_id = dbuf[8];
return 0;
#else
#warning "Missing implementation of drmParsePciDeviceInfo"
return -EINVAL;
@@ -5133,66 +4661,6 @@ drm_public int drmGetDeviceFromDevId(dev_t find_rdev, uint32_t flags, drmDeviceP
*device = d;
return 0;
#elif defined(__redox__)
/* On Redox there is no /dev/dri/ directory to enumerate.
* Instead, open /scheme/drm/card0 and query PCI info to
* construct a single drmDevice that serves as both primary
* and render node. */
drmDevicePtr devp;
char *pptr;
int max_node_length = 64, i;
size_t extra, psize;
uint8_t pbuf[22];
size_t prsize = 0;
int pret, fd;
if (device == NULL)
return -EINVAL;
if (drm_device_validate_flags(flags))
return -EINVAL;
fd = open("/scheme/drm/card0", O_RDWR | O_CLOEXEC);
if (fd < 0)
return -errno;
pret = redox_drm_exchange(fd, REDOX_DRM_IOCTL_GET_PCI_INFO, NULL, 0,
pbuf, sizeof(pbuf), &prsize);
close(fd);
if (pret != 0 || prsize < 17)
return -EIO;
extra = DRM_NODE_MAX * (sizeof(void *) + max_node_length);
psize = sizeof(drmDevice) + extra + sizeof(drmPciBusInfo) + sizeof(drmPciDeviceInfo);
devp = calloc(1, psize);
if (!devp)
return -ENOMEM;
devp->bustype = DRM_BUS_PCI;
/* Advertise both PRIMARY and RENDER — same path on Redox */
devp->available_nodes = (1 << DRM_NODE_PRIMARY) | (1 << DRM_NODE_RENDER);
pptr = (char *)devp + sizeof(drmDevice);
devp->nodes = (char **)pptr;
pptr += DRM_NODE_MAX * sizeof(void *);
for (i = 0; i < DRM_NODE_MAX; i++) { devp->nodes[i] = pptr; pptr += max_node_length; }
snprintf(devp->nodes[DRM_NODE_PRIMARY], max_node_length, "/scheme/drm/card0");
snprintf(devp->nodes[DRM_NODE_RENDER], max_node_length, "/scheme/drm/card0");
devp->businfo.pci = (drmPciBusInfoPtr)pptr;
pptr += sizeof(drmPciBusInfo);
devp->businfo.pci->domain = pbuf[10] | (pbuf[11] << 8) | (pbuf[12] << 16) | (pbuf[13] << 24);
devp->businfo.pci->bus = pbuf[14];
devp->businfo.pci->dev = pbuf[15];
devp->businfo.pci->func = pbuf[16];
devp->deviceinfo.pci = (drmPciDeviceInfoPtr)pptr;
devp->deviceinfo.pci->vendor_id = pbuf[0] | (pbuf[1] << 8);
devp->deviceinfo.pci->device_id = pbuf[2] | (pbuf[3] << 8);
devp->deviceinfo.pci->subvendor_id = pbuf[4] | (pbuf[5] << 8);
devp->deviceinfo.pci->subdevice_id = pbuf[6] | (pbuf[7] << 8);
devp->deviceinfo.pci->revision_id = pbuf[8];
*device = devp;
return 0;
#else
drmDevicePtr local_devices[MAX_DRM_NODES];
@@ -5293,66 +4761,6 @@ drm_public int drmGetNodeTypeFromDevId(dev_t devid)
*/
drm_public int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
{
#if defined(__redox__)
uint8_t pbuf[22];
size_t prsize = 0;
int pret;
uint16_t pvendor_id, pdevice_id, psubvendor_id, psubdevice_id, pdomain;
uint8_t prevision_id, pbus, pdev, pfunc;
const char *pnode;
int max_node_length, i;
size_t extra, psize;
drmDevicePtr devp;
char *pptr;
pret = redox_drm_exchange(fd, REDOX_DRM_IOCTL_GET_PCI_INFO, NULL, 0,
pbuf, sizeof(pbuf), &prsize);
if (pret != 0 || prsize < 17)
return -EIO;
pvendor_id = pbuf[0] | (pbuf[1] << 8);
pdevice_id = pbuf[2] | (pbuf[3] << 8);
psubvendor_id = pbuf[4] | (pbuf[5] << 8);
psubdevice_id = pbuf[6] | (pbuf[7] << 8);
prevision_id = pbuf[8];
pdomain = pbuf[10] | (pbuf[11] << 8) | (pbuf[12] << 16) | (pbuf[13] << 24);
pbus = pbuf[14];
pdev = pbuf[15];
pfunc = pbuf[16];
pnode = "/scheme/drm/card0";
max_node_length = 64;
extra = DRM_NODE_MAX * (sizeof(void *) + max_node_length);
psize = sizeof(drmDevice) + extra + sizeof(drmPciBusInfo) + sizeof(drmPciDeviceInfo);
devp = calloc(1, psize);
if (!devp)
return -ENOMEM;
devp->bustype = DRM_BUS_PCI;
devp->available_nodes = 1 << DRM_NODE_PRIMARY;
pptr = (char *)devp + sizeof(drmDevice);
devp->nodes = (char **)pptr;
pptr += DRM_NODE_MAX * sizeof(void *);
for (i = 0; i < DRM_NODE_MAX; i++) { devp->nodes[i] = pptr; pptr += max_node_length; }
snprintf(devp->nodes[DRM_NODE_PRIMARY], max_node_length, "%s", pnode);
devp->businfo.pci = (drmPciBusInfoPtr)pptr;
pptr += sizeof(drmPciBusInfo);
devp->businfo.pci->domain = pdomain;
devp->businfo.pci->bus = pbus;
devp->businfo.pci->dev = pdev;
devp->businfo.pci->func = pfunc;
devp->deviceinfo.pci = (drmPciDeviceInfoPtr)pptr;
devp->deviceinfo.pci->vendor_id = pvendor_id;
devp->deviceinfo.pci->device_id = pdevice_id;
devp->deviceinfo.pci->subvendor_id = psubvendor_id;
devp->deviceinfo.pci->subdevice_id = psubdevice_id;
devp->deviceinfo.pci->revision_id = prevision_id;
*device = devp;
return 0;
#else
struct stat sbuf;
if (fd == -1)
@@ -5365,7 +4773,6 @@ drm_public int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
return -EINVAL;
return drmGetDeviceFromDevId(sbuf.st_rdev, flags, device);
#endif
}
/**
@@ -50,7 +50,6 @@
#include "libdrm_macros.h"
#include "xf86drmMode.h"
#include "xf86drm.h"
#include "xf86drm_redox.h"
#include <drm.h>
#include <drm_fourcc.h>
#include <string.h>
@@ -69,212 +68,6 @@ static inline int DRM_IOCTL(int fd, unsigned long cmd, void *arg)
return ret < 0 ? -errno : ret;
}
static void* drmAllocCpy(char *array, int count, int entry_size);
#if defined(__redox__)
static void redox_drm_mode_from_wire(drmModeModeInfoPtr mode,
const struct redox_drm_mode_wire *wire,
const char *name)
{
memclear(*mode);
mode->clock = wire->clock;
mode->hdisplay = wire->hdisplay;
mode->hsync_start = wire->hsync_start;
mode->hsync_end = wire->hsync_end;
mode->htotal = wire->htotal;
mode->hskew = wire->hskew;
mode->vdisplay = wire->vdisplay;
mode->vsync_start = wire->vsync_start;
mode->vsync_end = wire->vsync_end;
mode->vtotal = wire->vtotal;
mode->vscan = wire->vscan;
mode->vrefresh = wire->vrefresh;
mode->flags = wire->flags;
mode->type = wire->type;
if (name) {
size_t name_len = strlen(name);
if (name_len >= DRM_DISPLAY_MODE_LEN)
name_len = DRM_DISPLAY_MODE_LEN - 1;
memcpy(mode->name, name, name_len);
}
}
static void redox_drm_mode_to_wire(struct redox_drm_mode_wire *wire,
const drmModeModeInfo *mode)
{
memclear(*wire);
wire->clock = mode->clock;
wire->hdisplay = mode->hdisplay;
wire->hsync_start = mode->hsync_start;
wire->hsync_end = mode->hsync_end;
wire->htotal = mode->htotal;
wire->hskew = mode->hskew;
wire->vdisplay = mode->vdisplay;
wire->vsync_start = mode->vsync_start;
wire->vsync_end = mode->vsync_end;
wire->vtotal = mode->vtotal;
wire->vscan = mode->vscan;
wire->vrefresh = mode->vrefresh;
wire->flags = mode->flags;
wire->type = mode->type;
}
static int redox_drm_fetch_resources(int fd,
struct redox_drm_resources_wire *header,
uint32_t **connector_ids)
{
void *response = NULL;
size_t response_size = 0;
size_t expected_size;
if (redox_drm_exchange_alloc(fd, REDOX_DRM_IOCTL_MODE_GETRESOURCES,
NULL, 0,
&response, &response_size) != 0) {
return -1;
}
if (response_size < sizeof(*header)) {
drmFree(response);
errno = EPROTO;
return -1;
}
memcpy(header, response, sizeof(*header));
expected_size = sizeof(*header) +
((size_t)header->connector_count * sizeof(uint32_t));
if (response_size < expected_size) {
drmFree(response);
errno = EPROTO;
return -1;
}
*connector_ids = NULL;
if (header->connector_count != 0) {
*connector_ids = drmAllocCpy((char *)response + sizeof(*header),
header->connector_count, sizeof(uint32_t));
if (!*connector_ids) {
drmFree(response);
errno = ENOMEM;
return -1;
}
}
drmFree(response);
return 0;
}
static int redox_drm_parse_connector_response(const void *blob, size_t blob_size,
struct redox_drm_connector_wire *header,
drmModeModeInfoPtr *modes_out)
{
const uint8_t *bytes = blob;
drmModeModeInfoPtr modes = NULL;
size_t offset = sizeof(*header);
uint32_t i;
if (blob_size < sizeof(*header)) {
errno = EPROTO;
return -1;
}
memcpy(header, bytes, sizeof(*header));
if (header->mode_count != 0) {
modes = drmMalloc(header->mode_count * sizeof(*modes));
if (!modes) {
errno = ENOMEM;
return -1;
}
}
for (i = 0; i < header->mode_count; ++i) {
struct redox_drm_mode_wire mode_wire;
const char *name;
size_t name_len;
if (blob_size - offset < sizeof(mode_wire)) {
drmFree(modes);
errno = EPROTO;
return -1;
}
memcpy(&mode_wire, bytes + offset, sizeof(mode_wire));
offset += sizeof(mode_wire);
name = (const char *)bytes + offset;
name_len = strnlen(name, blob_size - offset);
if (offset + name_len >= blob_size) {
drmFree(modes);
errno = EPROTO;
return -1;
}
redox_drm_mode_from_wire(&modes[i], &mode_wire, name);
offset += name_len + 1;
}
*modes_out = modes;
return 0;
}
static int redox_drm_fetch_connector(int fd, uint32_t connector_id,
struct redox_drm_connector_wire *header,
drmModeModeInfoPtr *modes_out)
{
void *response = NULL;
size_t response_size = 0;
int ret;
if (redox_drm_exchange_alloc(fd, REDOX_DRM_IOCTL_MODE_GETCONNECTOR,
&connector_id, sizeof(connector_id),
&response, &response_size) != 0) {
return -1;
}
ret = redox_drm_parse_connector_response(response, response_size,
header, modes_out);
drmFree(response);
return ret;
}
static uint32_t redox_drm_connector_type_id(int fd, uint32_t connector_id,
uint32_t connector_type)
{
struct redox_drm_resources_wire resources;
uint32_t *connector_ids = NULL;
uint32_t ordinal = 0;
uint32_t i;
if (redox_drm_fetch_resources(fd, &resources, &connector_ids) != 0)
return 0;
for (i = 0; i < resources.connector_count; ++i) {
struct redox_drm_connector_wire header;
drmModeModeInfoPtr modes = NULL;
if (redox_drm_fetch_connector(fd, connector_ids[i], &header, &modes) != 0)
break;
drmFree(modes);
if (header.connector_type == connector_type)
++ordinal;
if (header.connector_id == connector_id)
break;
}
drmFree(connector_ids);
return ordinal;
}
static int redox_drm_page_flip_unsupported(uint32_t flags)
{
if (flags & (DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_PAGE_FLIP_TARGET)) {
errno = EOPNOTSUPP;
return -1;
}
return 0;
}
#endif
/*
* Util functions
*/
@@ -360,104 +153,16 @@ drm_public void drmModeFreeEncoder(drmModeEncoderPtr ptr)
drm_public int drmIsKMS(int fd)
{
#if defined(__redox__)
struct redox_drm_resources_wire resources;
uint32_t *connector_ids = NULL;
int is_kms;
if (redox_drm_fetch_resources(fd, &resources, &connector_ids) != 0)
return 0;
is_kms = resources.crtc_count > 0 &&
resources.connector_count > 0 &&
resources.encoder_count > 0;
drmFree(connector_ids);
return is_kms;
#else
struct drm_mode_card_res res = {0};
if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res) != 0)
return 0;
return res.count_crtcs > 0 && res.count_connectors > 0 && res.count_encoders > 0;
#endif
}
drm_public drmModeResPtr drmModeGetResources(int fd)
{
#if defined(__redox__)
struct redox_drm_resources_wire resources;
uint32_t *connector_ids = NULL;
drmModeResPtr r = NULL;
uint32_t i;
if (redox_drm_fetch_resources(fd, &resources, &connector_ids) != 0)
return NULL;
r = drmMalloc(sizeof(*r));
if (!r) {
drmFree(connector_ids);
return NULL;
}
memclear(*r);
r->count_connectors = resources.connector_count;
r->count_crtcs = resources.crtc_count;
r->count_encoders = resources.encoder_count;
r->connectors = connector_ids;
if (resources.crtc_count != 0) {
r->crtcs = drmMalloc(resources.crtc_count * sizeof(*r->crtcs));
if (!r->crtcs)
goto err_allocs;
for (i = 0; i < resources.crtc_count; ++i)
r->crtcs[i] = i + 1;
}
if (resources.encoder_count != 0) {
r->encoders = drmMalloc(resources.encoder_count * sizeof(*r->encoders));
if (!r->encoders)
goto err_allocs;
memset(r->encoders, 0, resources.encoder_count * sizeof(*r->encoders));
}
for (i = 0; i < resources.connector_count; ++i) {
struct redox_drm_connector_wire connector;
drmModeModeInfoPtr modes = NULL;
uint32_t j;
if (redox_drm_fetch_connector(fd, connector_ids[i], &connector, &modes) != 0)
goto err_allocs;
if (i < resources.encoder_count)
r->encoders[i] = connector.encoder_id;
for (j = 0; j < connector.mode_count; ++j) {
uint32_t width = modes[j].hdisplay;
uint32_t height = modes[j].vdisplay;
if (r->min_width == 0 || width < r->min_width)
r->min_width = width;
if (width > r->max_width)
r->max_width = width;
if (r->min_height == 0 || height < r->min_height)
r->min_height = height;
if (height > r->max_height)
r->max_height = height;
}
drmFree(modes);
}
if (resources.encoder_count > resources.connector_count) {
for (i = resources.connector_count; i < resources.encoder_count; ++i)
r->encoders[i] = 0;
}
return r;
err_allocs:
drmModeFreeResources(r);
return NULL;
#else
struct drm_mode_card_res res, counts;
drmModeResPtr r = 0;
@@ -548,7 +253,6 @@ err_allocs:
drmFree(U642VOID(res.encoder_id_ptr));
return r;
#endif
}
@@ -556,26 +260,6 @@ drm_public int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t dep
uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
uint32_t *buf_id)
{
#if defined(__redox__)
struct redox_drm_add_fb_wire wire;
memclear(wire);
wire.width = width;
wire.height = height;
wire.pitch = pitch;
wire.bpp = bpp;
wire.depth = depth;
wire.handle = bo_handle;
if (redox_drm_exchange(fd, REDOX_DRM_IOCTL_MODE_ADDFB,
&wire, sizeof(wire),
&wire, sizeof(wire),
NULL) != 0) {
return -errno;
}
*buf_id = wire.fb_id;
return 0;
#else
struct drm_mode_fb_cmd f;
int ret;
@@ -592,7 +276,6 @@ drm_public int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t dep
*buf_id = f.fb_id;
return 0;
#endif
}
drm_public int drmModeAddFB2WithModifiers(int fd, uint32_t width,
@@ -634,22 +317,7 @@ drm_public int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
drm_public int drmModeRmFB(int fd, uint32_t bufferId)
{
#if defined(__redox__)
struct redox_drm_rm_fb_wire wire;
memclear(wire);
wire.fb_id = bufferId;
if (redox_drm_exchange(fd, REDOX_DRM_IOCTL_MODE_RMFB,
&wire, sizeof(wire),
NULL, 0,
NULL) != 0) {
return -errno;
}
return 0;
#else
return DRM_IOCTL(fd, DRM_IOCTL_MODE_RMFB, &bufferId);
#endif
}
drm_public int drmModeCloseFB(int fd, uint32_t buffer_id)
@@ -706,40 +374,6 @@ drm_public int drmModeDirtyFB(int fd, uint32_t bufferId,
drm_public drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
{
#if defined(__redox__)
struct redox_drm_get_crtc_wire wire;
drmModeCrtcPtr r;
memclear(wire);
wire.crtc_id = crtcId;
if (redox_drm_exchange(fd, REDOX_DRM_IOCTL_MODE_GETCRTC,
&wire, sizeof(wire),
&wire, sizeof(wire),
NULL) != 0) {
return NULL;
}
r = drmMalloc(sizeof(*r));
if (!r)
return NULL;
memclear(*r);
r->crtc_id = wire.crtc_id;
r->x = wire.x;
r->y = wire.y;
r->mode_valid = wire.mode_valid;
if (r->mode_valid) {
char mode_name[DRM_DISPLAY_MODE_LEN];
snprintf(mode_name, sizeof(mode_name), "%ux%u@%u",
wire.mode.hdisplay, wire.mode.vdisplay, wire.mode.vrefresh);
redox_drm_mode_from_wire(&r->mode, &wire.mode, mode_name);
r->width = wire.mode.hdisplay;
r->height = wire.mode.vdisplay;
}
r->buffer_id = wire.fb_id;
r->gamma_size = 0;
return r;
#else
struct drm_mode_crtc crtc;
drmModeCrtcPtr r;
@@ -768,47 +402,12 @@ drm_public drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
r->buffer_id = crtc.fb_id;
r->gamma_size = crtc.gamma_size;
return r;
#endif
}
drm_public int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
uint32_t x, uint32_t y, uint32_t *connectors, int count,
drmModeModeInfoPtr mode)
{
#if defined(__redox__)
struct redox_drm_set_crtc_wire wire;
if ((x != 0 || y != 0) && bufferId != 0) {
errno = EOPNOTSUPP;
return -errno;
}
if (count < 0 || count > 8) {
errno = EINVAL;
return -errno;
}
if (bufferId != 0 && !mode) {
errno = EINVAL;
return -errno;
}
memclear(wire);
wire.crtc_id = crtcId;
wire.fb_handle = bufferId;
wire.connector_count = count;
if (count > 0)
memcpy(wire.connectors, connectors, count * sizeof(*connectors));
if (mode)
redox_drm_mode_to_wire(&wire.mode, mode);
if (redox_drm_exchange(fd, REDOX_DRM_IOCTL_MODE_SETCRTC,
&wire, sizeof(wire),
NULL, 0,
NULL) != 0) {
return -errno;
}
return 0;
#else
struct drm_mode_crtc crtc;
memclear(crtc);
@@ -824,7 +423,6 @@ drm_public int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
}
return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETCRTC, &crtc);
#endif
}
/*
@@ -882,30 +480,6 @@ drm_public int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y)
*/
drm_public drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id)
{
#if defined(__redox__)
struct drm_mode_get_encoder enc;
drmModeEncoderPtr r = NULL;
memclear(enc);
enc.encoder_id = encoder_id;
if (redox_drm_exchange(fd, REDOX_DRM_IOCTL_MODE_GETENCODER,
&enc, sizeof(enc),
&enc, sizeof(enc),
NULL) != 0) {
return NULL;
}
r = drmMalloc(sizeof(*r));
if (!r)
return NULL;
r->encoder_id = enc.encoder_id;
r->crtc_id = enc.crtc_id;
r->encoder_type = enc.encoder_type;
r->possible_crtcs = enc.possible_crtcs;
r->possible_clones = enc.possible_clones;
return r;
#else
struct drm_mode_get_encoder enc;
drmModeEncoderPtr r = NULL;
@@ -925,7 +499,6 @@ drm_public drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id)
r->possible_clones = enc.possible_clones;
return r;
#endif
}
/*
@@ -934,50 +507,6 @@ drm_public drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id)
static drmModeConnectorPtr
_drmModeGetConnector(int fd, uint32_t connector_id, int probe)
{
#if defined(__redox__)
struct redox_drm_connector_wire conn;
drmModeConnectorPtr r = NULL;
drmModeModeInfoPtr modes = NULL;
(void)probe;
if (redox_drm_fetch_connector(fd, connector_id, &conn, &modes) != 0)
return NULL;
r = drmMalloc(sizeof(*r));
if (!r)
goto err_allocs;
memclear(*r);
r->connector_id = conn.connector_id;
r->encoder_id = conn.encoder_id;
r->connection = conn.connection;
r->mmWidth = conn.mm_width;
r->mmHeight = conn.mm_height;
r->subpixel = DRM_MODE_SUBPIXEL_UNKNOWN;
r->count_modes = conn.mode_count;
r->modes = modes;
r->count_props = 0;
r->props = NULL;
r->prop_values = NULL;
r->count_encoders = conn.encoder_id ? 1 : 0;
if (r->count_encoders != 0) {
r->encoders = drmMalloc(sizeof(*r->encoders));
if (!r->encoders)
goto err_allocs;
r->encoders[0] = conn.encoder_id;
}
r->connector_type = conn.connector_type;
r->connector_type_id = redox_drm_connector_type_id(fd,
conn.connector_id,
conn.connector_type);
return r;
err_allocs:
drmFree(modes);
drmFree(r ? r->encoders : NULL);
drmFree(r);
return NULL;
#else
struct drm_mode_get_connector conn, counts;
drmModeConnectorPtr r = NULL;
struct drm_mode_modeinfo stack_mode;
@@ -1079,7 +608,6 @@ err_allocs:
drmFree(U642VOID(conn.encoders_ptr));
return r;
#endif
}
drm_public drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
@@ -1572,27 +1100,6 @@ drm_public int drmHandleEvent(int fd, drmEventContextPtr evctx)
drm_public int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,
uint32_t flags, void *user_data)
{
#if defined(__redox__)
struct redox_drm_page_flip_wire flip;
uint64_t sequence;
(void)user_data;
if (redox_drm_page_flip_unsupported(flags) != 0)
return -errno;
memclear(flip);
flip.fb_handle = fb_id;
flip.crtc_id = crtc_id;
flip.flags = flags;
if (redox_drm_exchange(fd, REDOX_DRM_IOCTL_MODE_PAGE_FLIP,
&flip, sizeof(flip),
&sequence, sizeof(sequence),
NULL) != 0) {
return -errno;
}
return 0;
#else
struct drm_mode_crtc_page_flip flip;
memclear(flip);
@@ -1602,23 +1109,12 @@ drm_public int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,
flip.flags = flags;
return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip);
#endif
}
drm_public int drmModePageFlipTarget(int fd, uint32_t crtc_id, uint32_t fb_id,
uint32_t flags, void *user_data,
uint32_t target_vblank)
{
#if defined(__redox__)
(void)fd;
(void)crtc_id;
(void)fb_id;
(void)flags;
(void)user_data;
(void)target_vblank;
errno = EOPNOTSUPP;
return -errno;
#else
struct drm_mode_crtc_page_flip_target flip_target;
memclear(flip_target);
@@ -1629,7 +1125,6 @@ drm_public int drmModePageFlipTarget(int fd, uint32_t crtc_id, uint32_t fb_id,
flip_target.sequence = target_vblank;
return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip_target);
#endif
}
drm_public int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id,
@@ -2344,26 +1839,6 @@ drmModeCreateDumbBuffer(int fd, uint32_t width, uint32_t height, uint32_t bpp,
uint32_t flags, uint32_t *handle, uint32_t *pitch,
uint64_t *size)
{
#if defined(__redox__)
struct redox_drm_create_dumb_wire create;
memclear(create);
create.width = width;
create.height = height;
create.bpp = bpp;
create.flags = flags;
if (redox_drm_exchange(fd, REDOX_DRM_IOCTL_MODE_CREATE_DUMB,
&create, sizeof(create),
&create, sizeof(create),
NULL) != 0) {
return -errno;
}
*handle = create.handle;
*pitch = create.pitch;
*size = create.size;
return 0;
#else
int ret;
struct drm_mode_create_dumb create = {
.width = width,
@@ -2380,52 +1855,21 @@ drmModeCreateDumbBuffer(int fd, uint32_t width, uint32_t height, uint32_t bpp,
*pitch = create.pitch;
*size = create.size;
return 0;
#endif
}
drm_public int
drmModeDestroyDumbBuffer(int fd, uint32_t handle)
{
#if defined(__redox__)
struct redox_drm_destroy_dumb_wire destroy;
memclear(destroy);
destroy.handle = handle;
if (redox_drm_exchange(fd, REDOX_DRM_IOCTL_MODE_DESTROY_DUMB,
&destroy, sizeof(destroy),
NULL, 0,
NULL) != 0) {
return -errno;
}
return 0;
#else
struct drm_mode_destroy_dumb destroy = {
.handle = handle,
};
return DRM_IOCTL(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy);
#endif
}
drm_public int
drmModeMapDumbBuffer(int fd, uint32_t handle, uint64_t *offset)
{
#if defined(__redox__)
struct redox_drm_map_dumb_wire map;
memclear(map);
map.handle = handle;
if (redox_drm_exchange(fd, REDOX_DRM_IOCTL_MODE_MAP_DUMB,
&map, sizeof(map),
&map, sizeof(map),
NULL) != 0) {
return -errno;
}
*offset = map.offset;
return 0;
#else
int ret;
struct drm_mode_map_dumb map = {
.handle = handle,
@@ -2437,5 +1881,4 @@ drmModeMapDumbBuffer(int fd, uint32_t handle, uint64_t *offset)
*offset = map.offset;
return 0;
#endif
}
@@ -1,180 +0,0 @@
#ifndef _XF86DRM_REDOX_H_
#define _XF86DRM_REDOX_H_
#if defined(__redox__)
#include <stddef.h>
#include <stdint.h>
#define REDOX_DRM_IOCTL_BASE 0x00A0UL
#define REDOX_LINUX_IOCTL_NR(request) ((unsigned long)((request) & 0xffUL))
#define REDOX_LINUX_IOCTL_SIZE(request) (((unsigned long)(request) >> 16) & 0x3fffUL)
#define REDOX_DRM_IOCTL_MODE_GETRESOURCES (REDOX_DRM_IOCTL_BASE + 0)
#define REDOX_DRM_IOCTL_MODE_SETCRTC (REDOX_DRM_IOCTL_BASE + 2)
#define REDOX_DRM_IOCTL_MODE_GETCRTC (REDOX_DRM_IOCTL_BASE + 3)
#define REDOX_DRM_IOCTL_MODE_GETENCODER (REDOX_DRM_IOCTL_BASE + 6)
#define REDOX_DRM_IOCTL_MODE_GETCONNECTOR (REDOX_DRM_IOCTL_BASE + 7)
#define REDOX_DRM_IOCTL_MODE_PAGE_FLIP (REDOX_DRM_IOCTL_BASE + 16)
#define REDOX_DRM_IOCTL_MODE_CREATE_DUMB (REDOX_DRM_IOCTL_BASE + 18)
#define REDOX_DRM_IOCTL_MODE_MAP_DUMB (REDOX_DRM_IOCTL_BASE + 19)
#define REDOX_DRM_IOCTL_MODE_DESTROY_DUMB (REDOX_DRM_IOCTL_BASE + 20)
#define REDOX_DRM_IOCTL_MODE_ADDFB (REDOX_DRM_IOCTL_BASE + 21)
#define REDOX_DRM_IOCTL_MODE_RMFB (REDOX_DRM_IOCTL_BASE + 22)
#define REDOX_DRM_IOCTL_GET_CAP (REDOX_DRM_IOCTL_BASE + 23)
#define REDOX_DRM_IOCTL_SET_CLIENT_CAP (REDOX_DRM_IOCTL_BASE + 24)
#define REDOX_DRM_IOCTL_VERSION (REDOX_DRM_IOCTL_BASE + 25)
#define REDOX_DRM_IOCTL_GEM_CLOSE (REDOX_DRM_IOCTL_BASE + 27)
#define REDOX_DRM_IOCTL_PRIME_HANDLE_TO_FD (REDOX_DRM_IOCTL_BASE + 29)
#define REDOX_DRM_IOCTL_PRIME_FD_TO_HANDLE (REDOX_DRM_IOCTL_BASE + 30)
#define REDOX_DRM_IOCTL_VIRTGPU_MAP (REDOX_DRM_IOCTL_BASE + 31)
#define REDOX_DRM_IOCTL_VIRTGPU_EXECBUFFER (REDOX_DRM_IOCTL_BASE + 32)
#define REDOX_DRM_IOCTL_VIRTGPU_GETPARAM (REDOX_DRM_IOCTL_BASE + 33)
#define REDOX_DRM_IOCTL_VIRTGPU_RESOURCE_CREATE (REDOX_DRM_IOCTL_BASE + 34)
#define REDOX_DRM_IOCTL_VIRTGPU_RESOURCE_INFO (REDOX_DRM_IOCTL_BASE + 35)
#define REDOX_DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST (REDOX_DRM_IOCTL_BASE + 36)
#define REDOX_DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST (REDOX_DRM_IOCTL_BASE + 37)
#define REDOX_DRM_IOCTL_VIRTGPU_WAIT (REDOX_DRM_IOCTL_BASE + 38)
#define REDOX_DRM_IOCTL_VIRTGPU_GET_CAPS (REDOX_DRM_IOCTL_BASE + 39)
#define REDOX_DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB (REDOX_DRM_IOCTL_BASE + 40)
#define REDOX_DRM_IOCTL_VIRTGPU_CONTEXT_INIT (REDOX_DRM_IOCTL_BASE + 41)
#define REDOX_DRM_IOCTL_GET_MAGIC (REDOX_DRM_IOCTL_BASE + 33)
#define REDOX_DRM_IOCTL_AUTH_MAGIC (REDOX_DRM_IOCTL_BASE + 34)
#define REDOX_DRM_IOCTL_SET_MASTER (REDOX_DRM_IOCTL_BASE + 35)
#define REDOX_DRM_IOCTL_DROP_MASTER (REDOX_DRM_IOCTL_BASE + 36)
#define REDOX_DRM_IOCTL_GET_PCI_INFO (REDOX_DRM_IOCTL_BASE + 0x60)
struct redox_drm_resources_wire {
uint32_t connector_count;
uint32_t crtc_count;
uint32_t encoder_count;
};
struct redox_drm_connector_wire {
uint32_t connector_id;
uint32_t connection;
uint32_t connector_type;
uint32_t mm_width;
uint32_t mm_height;
uint32_t encoder_id;
uint32_t mode_count;
};
struct redox_drm_mode_wire {
uint32_t clock;
uint16_t hdisplay;
uint16_t hsync_start;
uint16_t hsync_end;
uint16_t htotal;
uint16_t hskew;
uint16_t vdisplay;
uint16_t vsync_start;
uint16_t vsync_end;
uint16_t vtotal;
uint16_t vscan;
uint32_t vrefresh;
uint32_t flags;
uint32_t type;
};
struct redox_drm_set_crtc_wire {
uint32_t crtc_id;
uint32_t fb_handle;
uint32_t connector_count;
uint32_t connectors[8];
struct redox_drm_mode_wire mode;
};
struct redox_drm_page_flip_wire {
uint32_t crtc_id;
uint32_t fb_handle;
uint32_t flags;
};
struct redox_drm_create_dumb_wire {
uint32_t width;
uint32_t height;
uint32_t bpp;
uint32_t flags;
uint32_t pitch;
uint32_t reserved0;
uint64_t size;
uint32_t handle;
uint32_t reserved1;
};
struct redox_drm_map_dumb_wire {
uint32_t handle;
uint32_t pad;
uint64_t offset;
};
struct redox_drm_destroy_dumb_wire {
uint32_t handle;
};
struct redox_drm_add_fb_wire {
uint32_t width;
uint32_t height;
uint32_t pitch;
uint32_t bpp;
uint32_t depth;
uint32_t handle;
uint32_t fb_id;
};
struct redox_drm_rm_fb_wire {
uint32_t fb_id;
};
struct redox_drm_get_crtc_wire {
uint32_t crtc_id;
uint32_t fb_id;
uint32_t x;
uint32_t y;
uint32_t mode_valid;
struct redox_drm_mode_wire mode;
};
struct redox_drm_version_wire {
int32_t major;
int32_t minor;
int32_t patch;
char name[64];
};
struct redox_drm_prime_handle_to_fd_wire {
uint32_t handle;
uint32_t flags;
};
struct redox_drm_prime_handle_to_fd_response_wire {
int32_t fd;
uint32_t pad;
};
struct redox_drm_prime_fd_to_handle_wire {
int32_t fd;
uint32_t pad;
};
struct redox_drm_prime_fd_to_handle_response_wire {
uint32_t handle;
uint32_t pad;
};
unsigned long redox_translate_request(unsigned long linux_nr);
int redox_drm_simple_ioctl(int fd, unsigned long request, void *arg);
int redox_drm_exchange(int fd, unsigned long request_code,
const void *payload, size_t payload_size,
void *response, size_t response_capacity,
size_t *response_size);
int redox_drm_exchange_alloc(int fd, unsigned long request_code,
const void *payload, size_t payload_size,
void **response, size_t *response_size);
#endif
#endif
+21 -1
View File
@@ -15,7 +15,27 @@ dependencies = [
]
script = """
DYNAMIC_INIT
cookbook_meson -Ddocumentation=false -Dtests=false -Ddtd_validation=false -Dc_args=-Wno-error
# IMPORTANT: `-Dscanner=false` is required for the Redox build.
#
# libwayland's default `-Dscanner=true` builds a `wayland-scanner`
# executable for the *target* (Redox). The resulting binary has
# /lib/ld64.so.1 as its ELF interpreter (Redox's loader) and is
# useless on the build host. The pkgconfig that libwayland
# installs (wayland-scanner.pc) then points `wayland_scanner` to
# this Redox binary, and downstream consumers (mesa,
# wayland-protocols) pick it up via `dependency('wayland-scanner')`.
# When the cookbook's redoxer sandbox tries to exec it on the host,
# the host kernel can't find /lib/ld64.so.1 and the build fails
# with "required file not found".
#
# Disabling the scanner here means libwayland doesn't install
# wayland-scanner to the sysroot. Downstream consumers then fall
# through to the host's /usr/bin/wayland-scanner (which is a
# proper x86_64-linux-gnu binary that works on the build host).
# This matches what wayland-protocols already does in its own
# meson.build (see its redox.patch in the recipe).
cookbook_meson -Ddocumentation=false -Dtests=false -Ddtd_validation=false -Dscanner=false -Dc_args=-Wno-error
"""
[package]