19c65be7b1
- Add full VirtIO GPU driver with command submission, resource management, VirtQueue implementation, and transport layer; includes diagnostic probes for resource_create_2d ERR_INVALID_RESOURCE_ID investigation - Expand libdrm Redox support with DRM ioctl wrappers (ADDFB, RMFB, CREATE_DUMB, MAP_DUMB, DESTROY_DUMB, GET_RESOURCES, GET_CONNECTOR, GET_CRTC, SET_CRTC, MODE_OBJ_GET_PROPERTIES, etc.) and xf86drm_redox.h - Add redox-drm scheme handlers for VirtIO GPU-specific DRM ioctls (VIRTGPU_RESOURCE_CREATE, VIRTGPU_MAP, VIRTGPU_WAIT, VIRTGPU_INFO, etc.) - Add display stack recipes: freetype2, lcms2, libdisplay-info, libepoxy, libxcvt - Fix KWin build (recipe.toml expanded, kf6-ksvg added) - Fix KF6 CMakeLists for cross-compilation (attica, kcmutils, kcolorscheme, kcompletion, kconfigwidgets, kdeclarative, kiconthemes, kitemmodels, kitemviews, kjobwidgets, ktextwidgets, kwayland, kxmlgui, kpty, solid) - Add Qt6 futex support patch - Add relibc patches: P3 strtold, P3 ld-so search path, P5 DRM ioctl removal - Add base P4 pcid config scheme patch - Update driver-manager hotplug/config, PCI config in redox-driver-sys - Update greeter compositor and KDE session scripts - Update AGENTS.md with zero-tolerance stubs policy and project knowledge
1543 lines
37 KiB
Diff
1543 lines
37 KiB
Diff
diff -ruN source-old/include/drm/drm.h source/include/drm/drm.h
|
|
--- source-old/include/drm/drm.h
|
|
+++ source/include/drm/drm.h
|
|
@@ -44,7 +44,11 @@
|
|
#else /* One of the BSDs */
|
|
|
|
#include <stdint.h>
|
|
+#if defined(__redox__)
|
|
+#include <sys/ioctl.h>
|
|
+#else
|
|
#include <sys/ioccom.h>
|
|
+#endif
|
|
#include <sys/types.h>
|
|
typedef int8_t __s8;
|
|
typedef uint8_t __u8;
|
|
diff -ruN source-old/xf86drm.c source/xf86drm.c
|
|
--- source-old/xf86drm.c
|
|
+++ source/xf86drm.c
|
|
@@ -57,6 +57,19 @@
|
|
#ifdef MAJOR_IN_SYSMACROS
|
|
#include <sys/sysmacros.h>
|
|
#endif
|
|
+#if defined(__redox__)
|
|
+// From musl sys/sysmacros.h
|
|
+#define major(x) \
|
|
+ ((unsigned)( (((x)>>31>>1) & 0xfffff000) | (((x)>>8) & 0x00000fff) ))
|
|
+#define minor(x) \
|
|
+ ((unsigned)( (((x)>>12) & 0xffffff00) | ((x) & 0x000000ff) ))
|
|
+
|
|
+#define makedev(x,y) ( \
|
|
+ (((x)&0xfffff000ULL) << 32) | \
|
|
+ (((x)&0x00000fffULL) << 8) | \
|
|
+ (((y)&0xffffff00ULL) << 12) | \
|
|
+ (((y)&0x000000ffULL)) )
|
|
+#endif
|
|
#if HAVE_SYS_SYSCTL_H
|
|
#include <sys/sysctl.h>
|
|
#endif
|
|
@@ -75,6 +88,7 @@
|
|
#endif
|
|
|
|
#include "xf86drm.h"
|
|
+#include "xf86drm_redox.h"
|
|
#include "libdrm_macros.h"
|
|
#include "drm_fourcc.h"
|
|
|
|
@@ -300,13 +314,18 @@
|
|
uint64_t type = (modifier >> 52) & 0xf;
|
|
|
|
FILE *fp;
|
|
- size_t size = 0;
|
|
char *modifier_name = NULL;
|
|
bool result = false;
|
|
|
|
+#if defined(__redox__)
|
|
+ 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;
|
|
+#endif
|
|
|
|
switch (type) {
|
|
case DRM_FORMAT_MOD_ARM_TYPE_AFBC:
|
|
@@ -407,11 +426,16 @@
|
|
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;
|
|
+#endif
|
|
|
|
switch (tile_version) {
|
|
case AMD_FMT_MOD_TILE_VER_GFX9:
|
|
@@ -680,18 +704,259 @@
|
|
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;
|
|
+ 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 0x0C:
|
|
+ case 0xA6:
|
|
+ case 0xB3:
|
|
+ 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 (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)
|
|
@@ -823,6 +1088,21 @@
|
|
return NULL;
|
|
}
|
|
|
|
+static int drmGetNodePath(char *buf, size_t buf_len, int type, int minor)
|
|
+{
|
|
+ const char *dev_name = drmGetDeviceName(type);
|
|
+
|
|
+#if defined(__redox__)
|
|
+ if (type == DRM_NODE_RENDER)
|
|
+ return snprintf(buf, buf_len, "%s/" DRM_RENDER_MINOR_NAME, DRM_DIR_NAME);
|
|
+#endif
|
|
+
|
|
+ if (!dev_name)
|
|
+ return -1;
|
|
+
|
|
+ return snprintf(buf, buf_len, dev_name, DRM_DIR_NAME, minor);
|
|
+}
|
|
+
|
|
/**
|
|
* Open the DRM device, creating it if necessary.
|
|
*
|
|
@@ -839,7 +1119,6 @@
|
|
static int drmOpenDevice(dev_t dev, int minor, int type)
|
|
{
|
|
stat_t st;
|
|
- const char *dev_name = drmGetDeviceName(type);
|
|
char buf[DRM_NODE_NAME_MAX];
|
|
int fd;
|
|
mode_t devmode = DRM_DEV_MODE, serv_mode;
|
|
@@ -850,10 +1129,8 @@
|
|
gid_t group = DRM_DEV_GID;
|
|
#endif
|
|
|
|
- if (!dev_name)
|
|
+ if (drmGetNodePath(buf, sizeof(buf), type, minor) < 0)
|
|
return -EINVAL;
|
|
-
|
|
- sprintf(buf, dev_name, DRM_DIR_NAME, minor);
|
|
drmMsg("drmOpenDevice: node name is %s\n", buf);
|
|
|
|
if (drm_server_info && drm_server_info->get_perms) {
|
|
@@ -958,15 +1235,13 @@
|
|
{
|
|
int fd;
|
|
char buf[DRM_NODE_NAME_MAX];
|
|
- const char *dev_name = drmGetDeviceName(type);
|
|
|
|
if (create)
|
|
return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type);
|
|
|
|
- if (!dev_name)
|
|
+ if (drmGetNodePath(buf, sizeof(buf), type, minor) < 0)
|
|
return -EINVAL;
|
|
|
|
- sprintf(buf, dev_name, DRM_DIR_NAME, minor);
|
|
if ((fd = open(buf, O_RDWR | O_CLOEXEC)) >= 0)
|
|
return fd;
|
|
return -errno;
|
|
@@ -1060,6 +1335,7 @@
|
|
return -1;
|
|
}
|
|
|
|
+#if !defined(__redox__)
|
|
static const char *drmGetMinorName(int type)
|
|
{
|
|
switch (type) {
|
|
@@ -1071,6 +1347,7 @@
|
|
return NULL;
|
|
}
|
|
}
|
|
+#endif
|
|
|
|
/**
|
|
* Open the device by bus ID.
|
|
@@ -1168,7 +1445,11 @@
|
|
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");
|
|
@@ -1321,6 +1602,7 @@
|
|
* 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)
|
|
@@ -1330,6 +1612,7 @@
|
|
drmFree(v->desc);
|
|
drmFree(v);
|
|
}
|
|
+#endif
|
|
|
|
|
|
/**
|
|
@@ -1342,6 +1625,7 @@
|
|
* 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;
|
|
@@ -1354,6 +1638,7 @@
|
|
d->desc_len = s->desc_len;
|
|
d->desc = s->desc ? strdup(s->desc) : NULL;
|
|
}
|
|
+#endif
|
|
|
|
|
|
/**
|
|
@@ -1373,6 +1658,27 @@
|
|
*/
|
|
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;
|
|
+ return retval;
|
|
+ #else
|
|
drmVersionPtr retval;
|
|
drm_version_t *version = drmMalloc(sizeof(*version));
|
|
|
|
@@ -1403,6 +1709,7 @@
|
|
drmCopyVersion(retval, version);
|
|
drmFreeKernelVersion(version);
|
|
return retval;
|
|
+ #endif
|
|
}
|
|
|
|
|
|
@@ -3306,7 +3613,8 @@
|
|
d = sbuf.st_rdev;
|
|
|
|
for (i = 0; i < DRM_MAX_MINOR; i++) {
|
|
- snprintf(name, sizeof name, DRM_DEV_NAME, DRM_DIR_NAME, i);
|
|
+ if (drmGetNodePath(name, sizeof(name), DRM_NODE_PRIMARY, i) < 0)
|
|
+ return NULL;
|
|
if (stat(name, &sbuf) == 0 && sbuf.st_rdev == d)
|
|
break;
|
|
}
|
|
@@ -3366,6 +3674,23 @@
|
|
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;
|
|
|
|
@@ -3379,10 +3704,27 @@
|
|
|
|
*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;
|
|
|
|
@@ -3394,6 +3736,7 @@
|
|
|
|
*handle = args.handle;
|
|
return 0;
|
|
+ #endif
|
|
}
|
|
|
|
drm_public int drmCloseBufferHandle(int fd, uint32_t handle)
|
|
@@ -3495,7 +3838,6 @@
|
|
#else
|
|
struct stat sbuf;
|
|
char buf[PATH_MAX + 1];
|
|
- const char *dev_name = drmGetDeviceName(type);
|
|
unsigned int maj, min;
|
|
int n;
|
|
|
|
@@ -3508,11 +3850,10 @@
|
|
if (!drmNodeIsDRM(maj, min) || !S_ISCHR(sbuf.st_mode))
|
|
return NULL;
|
|
|
|
- if (!dev_name)
|
|
+ n = drmGetNodePath(buf, sizeof(buf), type, min);
|
|
+ if (n < 0)
|
|
return NULL;
|
|
-
|
|
- n = snprintf(buf, sizeof(buf), dev_name, DRM_DIR_NAME, min);
|
|
- if (n == -1 || n >= sizeof(buf))
|
|
+ if ((size_t)n >= sizeof(buf))
|
|
return NULL;
|
|
|
|
return strdup(buf);
|
|
@@ -4877,7 +5218,6 @@
|
|
#else
|
|
struct stat sbuf;
|
|
char node[PATH_MAX + 1];
|
|
- const char *dev_name;
|
|
int node_type;
|
|
int maj, min, n;
|
|
|
|
@@ -4894,12 +5234,8 @@
|
|
if (node_type == -1)
|
|
return NULL;
|
|
|
|
- dev_name = drmGetDeviceName(node_type);
|
|
- if (!dev_name)
|
|
- return NULL;
|
|
-
|
|
- n = snprintf(node, PATH_MAX, dev_name, DRM_DIR_NAME, min);
|
|
- if (n == -1 || n >= PATH_MAX)
|
|
+ n = drmGetNodePath(node, sizeof(node), node_type, min);
|
|
+ if (n < 0 || n >= PATH_MAX)
|
|
return NULL;
|
|
|
|
return strdup(node);
|
|
diff -ruN source-old/xf86drm.h source/xf86drm.h
|
|
--- source-old/xf86drm.h
|
|
+++ source/xf86drm.h
|
|
@@ -47,7 +47,7 @@
|
|
#define DRM_MAX_MINOR 64 /* deprecated */
|
|
#endif
|
|
|
|
-#if defined(__linux__)
|
|
+#if defined(__linux__) || defined(__redox__)
|
|
|
|
#define DRM_IOCTL_NR(n) _IOC_NR(n)
|
|
#define DRM_IOC_VOID _IOC_NONE
|
|
@@ -81,6 +81,12 @@
|
|
#define DRM_PRIMARY_MINOR_NAME "drm"
|
|
#define DRM_CONTROL_MINOR_NAME "drmC" /* deprecated */
|
|
#define DRM_RENDER_MINOR_NAME "drmR"
|
|
+#elif defined(__redox__)
|
|
+#define DRM_DIR_NAME "/scheme/drm"
|
|
+#define DRM_PRIMARY_MINOR_NAME "card"
|
|
+#define DRM_CONTROL_MINOR_NAME "controlD" /* deprecated */
|
|
+#define DRM_RENDER_MINOR_NAME "renderD"
|
|
+#define DRM_PROC_NAME "/proc/dri/" /* For backward Linux compatibility */
|
|
#else
|
|
#define DRM_DIR_NAME "/dev/dri"
|
|
#define DRM_PRIMARY_MINOR_NAME "card"
|
|
diff -ruN source-old/xf86drmMode.c source/xf86drmMode.c
|
|
--- source-old/xf86drmMode.c
|
|
+++ source/xf86drmMode.c
|
|
@@ -50,6 +50,7 @@
|
|
#include "libdrm_macros.h"
|
|
#include "xf86drmMode.h"
|
|
#include "xf86drm.h"
|
|
+#include "xf86drm_redox.h"
|
|
#include <drm.h>
|
|
#include <drm_fourcc.h>
|
|
#include <string.h>
|
|
@@ -68,6 +69,212 @@
|
|
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
|
|
*/
|
|
@@ -153,16 +360,104 @@
|
|
|
|
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;
|
|
|
|
@@ -253,6 +548,7 @@
|
|
drmFree(U642VOID(res.encoder_id_ptr));
|
|
|
|
return r;
|
|
+ #endif
|
|
}
|
|
|
|
|
|
@@ -260,6 +556,26 @@
|
|
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;
|
|
|
|
@@ -276,6 +592,7 @@
|
|
|
|
*buf_id = f.fb_id;
|
|
return 0;
|
|
+ #endif
|
|
}
|
|
|
|
drm_public int drmModeAddFB2WithModifiers(int fd, uint32_t width,
|
|
@@ -317,7 +634,22 @@
|
|
|
|
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)
|
|
@@ -374,6 +706,40 @@
|
|
|
|
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;
|
|
|
|
@@ -402,12 +768,47 @@
|
|
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);
|
|
@@ -423,6 +824,7 @@
|
|
}
|
|
|
|
return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETCRTC, &crtc);
|
|
+ #endif
|
|
}
|
|
|
|
/*
|
|
@@ -480,6 +882,30 @@
|
|
*/
|
|
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;
|
|
|
|
@@ -499,6 +925,7 @@
|
|
r->possible_clones = enc.possible_clones;
|
|
|
|
return r;
|
|
+ #endif
|
|
}
|
|
|
|
/*
|
|
@@ -507,6 +934,50 @@
|
|
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;
|
|
@@ -608,6 +1079,7 @@
|
|
drmFree(U642VOID(conn.encoders_ptr));
|
|
|
|
return r;
|
|
+ #endif
|
|
}
|
|
|
|
drm_public drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
|
|
@@ -1100,6 +1572,27 @@
|
|
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);
|
|
@@ -1109,12 +1602,23 @@
|
|
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);
|
|
@@ -1125,6 +1629,7 @@
|
|
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,
|
|
@@ -1839,6 +2344,26 @@
|
|
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,
|
|
@@ -1855,21 +2380,52 @@
|
|
*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,
|
|
@@ -1881,4 +2437,5 @@
|
|
|
|
*offset = map.offset;
|
|
return 0;
|
|
+ #endif
|
|
}
|
|
diff -ruN source-old/xf86drm_redox.h source/xf86drm_redox.h
|
|
--- source-old/xf86drm_redox.h
|
|
+++ source/xf86drm_redox.h
|
|
@@ -0,0 +1,162 @@
|
|
+#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)
|
|
+
|
|
+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;
|
|
+};
|
|
+
|
|
+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
|