fix: iwlwifi — complete linux-kpi mac80211 header + build fixes
linux-kpi mac80211.h: - Extract struct ieee80211_channel to top level (was nested in ieee80211_conf) - Add struct ieee80211_conf conf to struct ieee80211_hw - Change void* channel to struct ieee80211_channel* in bss_conf.chandef - Include linux/ieee80211.h (consolidate single channel definition) linux-kpi limits.h: new header with S8_MIN/S8_MAX/U8_MAX etc. iwlwifi build.rs: add linux_mvm.c to cc-rs compilation iwlwifi linux_mvm.c: add S8_MIN fallback define
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
#ifndef _LINUX_LIMITS_H
|
||||
#define _LINUX_LIMITS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define S8_MIN INT8_MIN
|
||||
#define S8_MAX INT8_MAX
|
||||
#define U8_MAX UINT8_MAX
|
||||
#define S16_MIN INT16_MIN
|
||||
#define S16_MAX INT16_MAX
|
||||
#define U16_MAX UINT16_MAX
|
||||
#define S32_MIN INT32_MIN
|
||||
#define S32_MAX INT32_MAX
|
||||
#define U32_MAX UINT32_MAX
|
||||
#define S64_MIN INT64_MIN
|
||||
#define S64_MAX INT64_MAX
|
||||
#define U64_MAX UINT64_MAX
|
||||
|
||||
#endif
|
||||
@@ -2,11 +2,34 @@
|
||||
#define _NET_MAC80211_H
|
||||
|
||||
#include "../linux/device.h"
|
||||
#include "../linux/ieee80211.h"
|
||||
#include "../linux/netdevice.h"
|
||||
#include "../linux/skbuff.h"
|
||||
#include "../linux/types.h"
|
||||
#include "cfg80211.h"
|
||||
|
||||
#define IEEE80211_CONF_PS (1U << 1)
|
||||
#define IEEE80211_CONF_IDLE (1U << 2)
|
||||
|
||||
#define IEEE80211_CONF_CHANGE_SMPS (1U << 1)
|
||||
#define IEEE80211_CONF_CHANGE_LISTEN_INTERVAL (1U << 2)
|
||||
#define IEEE80211_CONF_CHANGE_MONITOR (1U << 3)
|
||||
#define IEEE80211_CONF_CHANGE_PS (1U << 4)
|
||||
#define IEEE80211_CONF_CHANGE_POWER (1U << 5)
|
||||
#define IEEE80211_CONF_CHANGE_CHANNEL (1U << 6)
|
||||
|
||||
struct ieee80211_conf {
|
||||
u32 flags;
|
||||
int power_level;
|
||||
int dynamic_ps_timeout;
|
||||
struct {
|
||||
u32 center_freq;
|
||||
u16 band;
|
||||
struct ieee80211_channel *channel;
|
||||
} chandef;
|
||||
u32 listen_interval;
|
||||
};
|
||||
|
||||
struct ieee80211_hw {
|
||||
struct wiphy *wiphy;
|
||||
const struct ieee80211_ops *ops;
|
||||
@@ -14,6 +37,7 @@ struct ieee80211_hw {
|
||||
int registered;
|
||||
u32 extra_tx_headroom;
|
||||
u16 queues;
|
||||
struct ieee80211_conf conf;
|
||||
};
|
||||
|
||||
struct ieee80211_vif {
|
||||
@@ -39,30 +63,10 @@ struct ieee80211_bss_conf {
|
||||
struct {
|
||||
u32 center_freq;
|
||||
u16 band;
|
||||
void *channel;
|
||||
struct ieee80211_channel *channel;
|
||||
} chandef;
|
||||
};
|
||||
|
||||
#define IEEE80211_CONF_PS (1U << 1)
|
||||
#define IEEE80211_CONF_IDLE (1U << 2)
|
||||
|
||||
#define IEEE80211_CONF_CHANGE_SMPS (1U << 1)
|
||||
#define IEEE80211_CONF_CHANGE_LISTEN_INTERVAL (1U << 2)
|
||||
#define IEEE80211_CONF_CHANGE_MONITOR (1U << 3)
|
||||
#define IEEE80211_CONF_CHANGE_PS (1U << 4)
|
||||
#define IEEE80211_CONF_CHANGE_POWER (1U << 5)
|
||||
#define IEEE80211_CONF_CHANGE_CHANNEL (1U << 6)
|
||||
|
||||
struct ieee80211_conf {
|
||||
u32 flags;
|
||||
int power_level;
|
||||
int dynamic_ps_timeout;
|
||||
struct ieee80211_channel {
|
||||
u32 center_freq;
|
||||
} chandef;
|
||||
u32 listen_interval;
|
||||
};
|
||||
|
||||
struct ieee80211_rx_status {
|
||||
u16 freq;
|
||||
u32 band;
|
||||
|
||||
@@ -5,6 +5,7 @@ fn main() {
|
||||
|
||||
cc::Build::new()
|
||||
.file("src/linux_port.c")
|
||||
.file("src/linux_mvm.c")
|
||||
.include(linux_kpi_headers)
|
||||
.warnings(true)
|
||||
.compile("redbear_iwlwifi_linux_port");
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef S8_MIN
|
||||
#define S8_MIN INT8_MIN
|
||||
#endif
|
||||
|
||||
int rb_iwl_mvm_detect_format(const uint8_t *data, size_t len)
|
||||
{
|
||||
uint16_t mpdu_len;
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
#TODO: lcms2 stub — provides lcms2::lcms2 cmake target for KWin linking
|
||||
[source]
|
||||
path = "source"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
script = """
|
||||
DYNAMIC_INIT
|
||||
|
||||
mkdir -p "${COOKBOOK_STAGE}/usr/include"
|
||||
mkdir -p "${COOKBOOK_STAGE}/usr/lib/cmake/lcms2"
|
||||
|
||||
cat > "${COOKBOOK_STAGE}/usr/include/lcms2.h" << 'EOF'
|
||||
#pragma once
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
typedef void* cmsHPROFILE;
|
||||
typedef void* cmsHTRANSFORM;
|
||||
cmsHPROFILE cmsOpenProfileFromMem(const void *mem, size_t size) __attribute__((weak));
|
||||
void cmsCloseProfile(cmsHPROFILE hProfile) __attribute__((weak));
|
||||
cmsHTRANSFORM cmsCreateTransform(cmsHPROFILE input, uint32_t inType, cmsHPROFILE output, uint32_t outType, uint32_t intent, uint32_t flags) __attribute__((weak));
|
||||
void cmsDeleteTransform(cmsHTRANSFORM hTransform) __attribute__((weak));
|
||||
void cmsDoTransform(cmsHTRANSFORM hTransform, const void *in, void *out, unsigned int size) __attribute__((weak));
|
||||
cmsHPROFILE cmsCreate_sRGBProfile(void) __attribute__((weak));
|
||||
cmsHPROFILE cmsOpenProfileFromFile(const char *path, const char *mode) __attribute__((weak));
|
||||
uint32_t cmsGetProfileInfo(cmsHPROFILE hProfile, uint32_t info, const char *lang, const char *country, char *buffer, uint32_t buffer_size) __attribute__((weak));
|
||||
EOF
|
||||
|
||||
cat > stub_lcms2.c << 'CEOF'
|
||||
#include <stddef.h>
|
||||
|
||||
void *cmsOpenProfileFromMem(const void *m, size_t s) { (void)m; (void)s; return 0; }
|
||||
void cmsCloseProfile(void *p) { (void)p; }
|
||||
void *cmsCreateTransform(void *i, unsigned int it, void *o, unsigned int ot, unsigned int u, unsigned int f) { (void)i; (void)it; (void)o; (void)ot; (void)u; (void)f; return 0; }
|
||||
void cmsDeleteTransform(void *t) { (void)t; }
|
||||
void cmsDoTransform(void *t, const void *i, void *o, unsigned int s) { (void)t; (void)i; (void)o; (void)s; }
|
||||
void *cmsCreate_sRGBProfile(void) { return 0; }
|
||||
void *cmsOpenProfileFromFile(const char *p, const char *m) { (void)p; (void)m; return 0; }
|
||||
unsigned int cmsGetProfileInfo(void *h, unsigned int i, const char *l, const char *c, char *b, unsigned int s) { (void)h; (void)i; (void)l; (void)c; (void)b; (void)s; return 0; }
|
||||
CEOF
|
||||
|
||||
x86_64-unknown-redox-gcc -shared -fPIC -o "${COOKBOOK_STAGE}/usr/lib/liblcms2.so" stub_lcms2.c
|
||||
|
||||
cat > "${COOKBOOK_STAGE}/usr/lib/cmake/lcms2/lcms2Config.cmake" << 'EOF'
|
||||
if(NOT TARGET lcms2::lcms2)
|
||||
add_library(lcms2::lcms2 SHARED IMPORTED)
|
||||
set_target_properties(lcms2::lcms2 PROPERTIES
|
||||
IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/../../../lib/liblcms2.so"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/../../../include"
|
||||
)
|
||||
endif()
|
||||
set(lcms2_FOUND TRUE)
|
||||
set(lcms2_VERSION "2.15")
|
||||
EOF
|
||||
|
||||
cat > "${COOKBOOK_STAGE}/usr/lib/cmake/lcms2/lcms2ConfigVersion.cmake" << 'EOF'
|
||||
set(PACKAGE_VERSION "2.15")
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
EOF
|
||||
"""
|
||||
@@ -1,34 +0,0 @@
|
||||
#TODO: bounded libdisplay-info shim for the KWin reduced path — parses base EDID vendor/product, strings, physical size, chromaticity, detailed timings, and preferred-timing metadata; CTA/DisplayID remain unsupported
|
||||
[source]
|
||||
path = "source"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
script = """
|
||||
DYNAMIC_INIT
|
||||
|
||||
mkdir -p "${COOKBOOK_STAGE}/usr/include/libdisplay-info"
|
||||
mkdir -p "${COOKBOOK_STAGE}/usr/lib"
|
||||
mkdir -p "${COOKBOOK_STAGE}/usr/lib/pkgconfig"
|
||||
|
||||
cp -R "${COOKBOOK_SOURCE}/include/libdisplay-info/." "${COOKBOOK_STAGE}/usr/include/libdisplay-info/"
|
||||
|
||||
x86_64-unknown-redox-gcc -shared -fPIC \
|
||||
-Wl,-soname,libdisplay-info.so \
|
||||
-I"${COOKBOOK_SOURCE}/include" \
|
||||
-o "${COOKBOOK_STAGE}/usr/lib/libdisplay-info.so" \
|
||||
"${COOKBOOK_SOURCE}/stub_di.c"
|
||||
|
||||
cat > "${COOKBOOK_STAGE}/usr/lib/pkgconfig/libdisplay-info.pc" << 'EOF'
|
||||
prefix=/usr
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: libdisplay-info
|
||||
Description: libdisplay-info compatibility shim for Redox
|
||||
Version: 0.2.0
|
||||
Libs: -L${libdir} -ldisplay-info
|
||||
Cflags: -I${includedir}
|
||||
EOF
|
||||
"""
|
||||
@@ -1,3 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "info.h"
|
||||
@@ -1,3 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "info.h"
|
||||
@@ -1,3 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "info.h"
|
||||
@@ -1,108 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct di_info;
|
||||
struct di_edid;
|
||||
struct di_edid_ext;
|
||||
struct di_edid_cta;
|
||||
struct di_displayid;
|
||||
struct di_cta_data_block;
|
||||
struct di_displayid_data_block;
|
||||
|
||||
struct di_edid_vendor_product {
|
||||
char manufacturer[4];
|
||||
int product;
|
||||
int serial;
|
||||
int manufacture_week;
|
||||
int manufacture_year;
|
||||
int model_year;
|
||||
};
|
||||
|
||||
struct di_edid_chromaticity_coords {
|
||||
float red_x;
|
||||
float red_y;
|
||||
float green_x;
|
||||
float green_y;
|
||||
float blue_x;
|
||||
float blue_y;
|
||||
float white_x;
|
||||
float white_y;
|
||||
};
|
||||
|
||||
struct di_cta_hdr_static_metadata_eotfs {
|
||||
bool pq;
|
||||
};
|
||||
|
||||
struct di_cta_hdr_static_metadata_block {
|
||||
int desired_content_min_luminance;
|
||||
int desired_content_max_luminance;
|
||||
int desired_content_max_frame_avg_luminance;
|
||||
const struct di_cta_hdr_static_metadata_eotfs *eotfs;
|
||||
};
|
||||
|
||||
struct di_cta_colorimetry_block {
|
||||
bool bt2020_rgb;
|
||||
};
|
||||
|
||||
struct di_displayid_display_params {
|
||||
int horiz_pixels;
|
||||
int vert_pixels;
|
||||
};
|
||||
|
||||
struct di_displayid_type_i_ii_vii_timing {
|
||||
bool preferred;
|
||||
int horiz_active;
|
||||
int vert_active;
|
||||
};
|
||||
|
||||
struct di_edid_misc_features {
|
||||
bool preferred_timing_is_native;
|
||||
};
|
||||
|
||||
struct di_edid_detailed_timing_def {
|
||||
int horiz_image_mm;
|
||||
int vert_image_mm;
|
||||
int horiz_video;
|
||||
int vert_video;
|
||||
};
|
||||
|
||||
struct di_edid_screen_size {
|
||||
int width_cm;
|
||||
int height_cm;
|
||||
};
|
||||
|
||||
const struct di_info *di_info_parse_edid(const void *data, size_t size);
|
||||
void di_info_destroy(const struct di_info *info);
|
||||
const struct di_edid *di_info_get_edid(const struct di_info *info);
|
||||
char *di_info_get_model(const struct di_info *info);
|
||||
char *di_info_get_serial(const struct di_info *info);
|
||||
|
||||
const struct di_edid_detailed_timing_def *const *di_edid_get_detailed_timing_defs(const struct di_edid *edid);
|
||||
const struct di_edid_screen_size *di_edid_get_screen_size(const struct di_edid *edid);
|
||||
const struct di_edid_vendor_product *di_edid_get_vendor_product(const struct di_edid *edid);
|
||||
const struct di_edid_chromaticity_coords *di_edid_get_chromaticity_coords(const struct di_edid *edid);
|
||||
const struct di_edid_ext *const *di_edid_get_extensions(const struct di_edid *edid);
|
||||
const struct di_edid_misc_features *di_edid_get_misc_features(const struct di_edid *edid);
|
||||
|
||||
const struct di_edid_cta *di_edid_ext_get_cta(const struct di_edid_ext *ext);
|
||||
const struct di_displayid *di_edid_ext_get_displayid(const struct di_edid_ext *ext);
|
||||
|
||||
const struct di_cta_data_block *const *di_edid_cta_get_data_blocks(const struct di_edid_cta *cta);
|
||||
const struct di_cta_hdr_static_metadata_block *di_cta_data_block_get_hdr_static_metadata(const struct di_cta_data_block *block);
|
||||
const struct di_cta_colorimetry_block *di_cta_data_block_get_colorimetry(const struct di_cta_data_block *block);
|
||||
|
||||
const struct di_displayid_data_block *const *di_displayid_get_data_blocks(const struct di_displayid *displayid);
|
||||
const struct di_displayid_display_params *di_displayid_data_block_get_display_params(const struct di_displayid_data_block *block);
|
||||
const struct di_displayid_type_i_ii_vii_timing *const *di_displayid_data_block_get_type_i_timings(const struct di_displayid_data_block *block);
|
||||
const struct di_displayid_type_i_ii_vii_timing *const *di_displayid_data_block_get_type_ii_timings(const struct di_displayid_data_block *block);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,401 +0,0 @@
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "include/libdisplay-info/info.h"
|
||||
|
||||
#define EDID_BLOCK_SIZE 128
|
||||
#define EDID_DESCRIPTOR_COUNT 4
|
||||
#define EDID_DESCRIPTOR_OFFSET 54
|
||||
|
||||
struct di_edid {
|
||||
struct di_edid_vendor_product vendor_product;
|
||||
struct di_edid_chromaticity_coords chromaticity;
|
||||
struct di_edid_screen_size screen_size;
|
||||
struct di_edid_misc_features misc_features;
|
||||
bool has_chromaticity;
|
||||
struct di_edid_detailed_timing_def *detailed_timing_storage;
|
||||
const struct di_edid_detailed_timing_def **detailed_timings;
|
||||
const struct di_edid_ext **extensions;
|
||||
};
|
||||
|
||||
struct di_info {
|
||||
struct di_edid edid;
|
||||
char *model;
|
||||
char *serial;
|
||||
};
|
||||
|
||||
static const uint8_t edid_header[8] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
|
||||
static const struct di_edid_detailed_timing_def *empty_detailed_timings[] = { NULL };
|
||||
static const struct di_edid_ext *empty_edid_exts[] = { NULL };
|
||||
static const struct di_cta_data_block *empty_cta_blocks[] = { NULL };
|
||||
static const struct di_displayid_data_block *empty_displayid_blocks[] = { NULL };
|
||||
static const struct di_displayid_type_i_ii_vii_timing *empty_timings[] = { NULL };
|
||||
static const struct di_edid_screen_size empty_screen_size = { 0, 0 };
|
||||
|
||||
static char *dup_string(const char *value)
|
||||
{
|
||||
size_t len;
|
||||
char *copy;
|
||||
|
||||
if (!value) {
|
||||
value = "";
|
||||
}
|
||||
|
||||
len = strlen(value) + 1;
|
||||
copy = malloc(len);
|
||||
if (!copy) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(copy, value, len);
|
||||
return copy;
|
||||
}
|
||||
|
||||
static bool has_nonzero_bytes(const uint8_t *data, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (data[i] != 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool validate_edid_block(const uint8_t *block)
|
||||
{
|
||||
uint8_t checksum = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < EDID_BLOCK_SIZE; i++) {
|
||||
checksum = (uint8_t)(checksum + block[i]);
|
||||
}
|
||||
|
||||
return checksum == 0;
|
||||
}
|
||||
|
||||
static uint16_t read_le_u16(const uint8_t *data)
|
||||
{
|
||||
return (uint16_t)data[0] | ((uint16_t)data[1] << 8);
|
||||
}
|
||||
|
||||
static uint32_t read_le_u32(const uint8_t *data)
|
||||
{
|
||||
return (uint32_t)data[0] | ((uint32_t)data[1] << 8) | ((uint32_t)data[2] << 16) | ((uint32_t)data[3] << 24);
|
||||
}
|
||||
|
||||
static float decode_chromaticity_value(uint8_t high_bits, uint8_t low_bits)
|
||||
{
|
||||
return (float)(((unsigned int)high_bits << 2) | low_bits) / 1024.0f;
|
||||
}
|
||||
|
||||
static void decode_manufacturer_id(const uint8_t *base, char manufacturer[4])
|
||||
{
|
||||
manufacturer[0] = (char)('A' + ((base[8] >> 2) & 0x1f) - 1);
|
||||
manufacturer[1] = (char)('A' + (((base[8] & 0x03) << 3) | ((base[9] >> 5) & 0x07)) - 1);
|
||||
manufacturer[2] = (char)('A' + (base[9] & 0x1f) - 1);
|
||||
manufacturer[3] = '\0';
|
||||
|
||||
if (!isupper((unsigned char)manufacturer[0]) || !isupper((unsigned char)manufacturer[1]) || !isupper((unsigned char)manufacturer[2])) {
|
||||
memcpy(manufacturer, "???", 4);
|
||||
}
|
||||
}
|
||||
|
||||
static char *parse_descriptor_string(const uint8_t *descriptor)
|
||||
{
|
||||
char buffer[14];
|
||||
size_t out_len = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 5; i < 18; i++) {
|
||||
const uint8_t value = descriptor[i];
|
||||
|
||||
if (value == 0x00 || value == 0x0a || value == 0x0d) {
|
||||
break;
|
||||
}
|
||||
if (value < 0x20 || value > 0x7e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
buffer[out_len++] = (char)value;
|
||||
}
|
||||
|
||||
while (out_len > 0 && isspace((unsigned char)buffer[out_len - 1])) {
|
||||
out_len--;
|
||||
}
|
||||
buffer[out_len] = '\0';
|
||||
|
||||
return dup_string(buffer);
|
||||
}
|
||||
|
||||
static bool parse_detailed_timing(const uint8_t *descriptor, struct di_edid_detailed_timing_def *timing)
|
||||
{
|
||||
const uint16_t pixel_clock = read_le_u16(descriptor);
|
||||
|
||||
if (pixel_clock == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
timing->horiz_video = (int)(descriptor[2] | ((descriptor[4] & 0xf0) << 4));
|
||||
timing->vert_video = (int)(descriptor[5] | ((descriptor[7] & 0xf0) << 4));
|
||||
timing->horiz_image_mm = (int)(descriptor[12] | ((descriptor[14] & 0xf0) << 4));
|
||||
timing->vert_image_mm = (int)(descriptor[13] | ((descriptor[14] & 0x0f) << 8));
|
||||
|
||||
return timing->horiz_video > 0 && timing->vert_video > 0;
|
||||
}
|
||||
|
||||
static bool populate_detailed_timings(struct di_edid *edid, const uint8_t *base)
|
||||
{
|
||||
struct di_edid_detailed_timing_def parsed[EDID_DESCRIPTOR_COUNT];
|
||||
size_t count = 0;
|
||||
size_t i;
|
||||
|
||||
edid->detailed_timings = empty_detailed_timings;
|
||||
|
||||
for (i = 0; i < EDID_DESCRIPTOR_COUNT; i++) {
|
||||
const uint8_t *descriptor = base + EDID_DESCRIPTOR_OFFSET + (i * 18);
|
||||
|
||||
if (parse_detailed_timing(descriptor, &parsed[count])) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
edid->detailed_timing_storage = calloc(count, sizeof(*edid->detailed_timing_storage));
|
||||
edid->detailed_timings = calloc(count + 1, sizeof(*edid->detailed_timings));
|
||||
if (!edid->detailed_timing_storage || !edid->detailed_timings) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
edid->detailed_timing_storage[i] = parsed[i];
|
||||
edid->detailed_timings[i] = &edid->detailed_timing_storage[i];
|
||||
}
|
||||
|
||||
edid->detailed_timings[count] = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void populate_vendor_product(struct di_edid *edid, const uint8_t *base)
|
||||
{
|
||||
const int manufacture_year = (int)base[17] + 1990;
|
||||
const bool has_model_year = base[16] == 0xff;
|
||||
|
||||
decode_manufacturer_id(base, edid->vendor_product.manufacturer);
|
||||
edid->vendor_product.product = (int)read_le_u16(base + 10);
|
||||
edid->vendor_product.serial = (int)read_le_u32(base + 12);
|
||||
edid->vendor_product.manufacture_week = has_model_year ? 0 : (int)base[16];
|
||||
edid->vendor_product.manufacture_year = has_model_year ? 0 : manufacture_year;
|
||||
edid->vendor_product.model_year = has_model_year ? manufacture_year : 0;
|
||||
}
|
||||
|
||||
static void populate_chromaticity(struct di_edid *edid, const uint8_t *base)
|
||||
{
|
||||
if (!has_nonzero_bytes(base + 25, 10)) {
|
||||
edid->has_chromaticity = false;
|
||||
return;
|
||||
}
|
||||
|
||||
edid->chromaticity.red_x = decode_chromaticity_value(base[27], (base[25] >> 6) & 0x03);
|
||||
edid->chromaticity.red_y = decode_chromaticity_value(base[28], (base[25] >> 4) & 0x03);
|
||||
edid->chromaticity.green_x = decode_chromaticity_value(base[29], (base[25] >> 2) & 0x03);
|
||||
edid->chromaticity.green_y = decode_chromaticity_value(base[30], base[25] & 0x03);
|
||||
edid->chromaticity.blue_x = decode_chromaticity_value(base[31], (base[26] >> 6) & 0x03);
|
||||
edid->chromaticity.blue_y = decode_chromaticity_value(base[32], (base[26] >> 4) & 0x03);
|
||||
edid->chromaticity.white_x = decode_chromaticity_value(base[33], (base[26] >> 2) & 0x03);
|
||||
edid->chromaticity.white_y = decode_chromaticity_value(base[34], base[26] & 0x03);
|
||||
edid->has_chromaticity = true;
|
||||
}
|
||||
|
||||
static bool populate_strings(struct di_info *info, const uint8_t *base)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < EDID_DESCRIPTOR_COUNT; i++) {
|
||||
const uint8_t *descriptor = base + EDID_DESCRIPTOR_OFFSET + (i * 18);
|
||||
|
||||
if (descriptor[0] != 0x00 || descriptor[1] != 0x00 || descriptor[2] != 0x00) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (descriptor[3] == 0xfc && !info->model) {
|
||||
info->model = parse_descriptor_string(descriptor);
|
||||
} else if (descriptor[3] == 0xff && !info->serial) {
|
||||
info->serial = parse_descriptor_string(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
if (!info->model) {
|
||||
info->model = dup_string("");
|
||||
}
|
||||
if (!info->serial) {
|
||||
if (info->edid.vendor_product.serial != 0) {
|
||||
char serial_buffer[32];
|
||||
|
||||
snprintf(serial_buffer, sizeof(serial_buffer), "%u", (unsigned int)info->edid.vendor_product.serial);
|
||||
info->serial = dup_string(serial_buffer);
|
||||
} else {
|
||||
info->serial = dup_string("");
|
||||
}
|
||||
}
|
||||
|
||||
return info->model && info->serial;
|
||||
}
|
||||
|
||||
const struct di_info *di_info_parse_edid(const void *data, size_t size)
|
||||
{
|
||||
const uint8_t *base = data;
|
||||
struct di_info *info;
|
||||
|
||||
if (!base || size < EDID_BLOCK_SIZE) {
|
||||
return NULL;
|
||||
}
|
||||
if (memcmp(base, edid_header, sizeof(edid_header)) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (!validate_edid_block(base)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
info = calloc(1, sizeof(*info));
|
||||
if (!info) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
info->edid.screen_size.width_cm = (int)base[21];
|
||||
info->edid.screen_size.height_cm = (int)base[22];
|
||||
info->edid.misc_features.preferred_timing_is_native = (base[24] & 0x02) != 0;
|
||||
info->edid.extensions = empty_edid_exts;
|
||||
|
||||
populate_vendor_product(&info->edid, base);
|
||||
populate_chromaticity(&info->edid, base);
|
||||
if (!populate_detailed_timings(&info->edid, base) || !populate_strings(info, base)) {
|
||||
di_info_destroy(info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
void di_info_destroy(const struct di_info *info)
|
||||
{
|
||||
struct di_info *mutable_info = (struct di_info *)info;
|
||||
|
||||
if (!mutable_info) {
|
||||
return;
|
||||
}
|
||||
|
||||
free(mutable_info->model);
|
||||
free(mutable_info->serial);
|
||||
if (mutable_info->edid.detailed_timings != empty_detailed_timings) {
|
||||
free((void *)mutable_info->edid.detailed_timings);
|
||||
}
|
||||
free(mutable_info->edid.detailed_timing_storage);
|
||||
free(mutable_info);
|
||||
}
|
||||
|
||||
const struct di_edid *di_info_get_edid(const struct di_info *info)
|
||||
{
|
||||
return info ? &info->edid : NULL;
|
||||
}
|
||||
|
||||
char *di_info_get_model(const struct di_info *info)
|
||||
{
|
||||
return dup_string(info ? info->model : "");
|
||||
}
|
||||
|
||||
char *di_info_get_serial(const struct di_info *info)
|
||||
{
|
||||
return dup_string(info ? info->serial : "");
|
||||
}
|
||||
|
||||
const struct di_edid_detailed_timing_def *const *di_edid_get_detailed_timing_defs(const struct di_edid *edid)
|
||||
{
|
||||
return edid && edid->detailed_timings ? edid->detailed_timings : empty_detailed_timings;
|
||||
}
|
||||
|
||||
const struct di_edid_screen_size *di_edid_get_screen_size(const struct di_edid *edid)
|
||||
{
|
||||
return edid ? &edid->screen_size : &empty_screen_size;
|
||||
}
|
||||
|
||||
const struct di_edid_vendor_product *di_edid_get_vendor_product(const struct di_edid *edid)
|
||||
{
|
||||
return edid ? &edid->vendor_product : NULL;
|
||||
}
|
||||
|
||||
const struct di_edid_chromaticity_coords *di_edid_get_chromaticity_coords(const struct di_edid *edid)
|
||||
{
|
||||
return edid && edid->has_chromaticity ? &edid->chromaticity : NULL;
|
||||
}
|
||||
|
||||
const struct di_edid_ext *const *di_edid_get_extensions(const struct di_edid *edid)
|
||||
{
|
||||
return edid && edid->extensions ? edid->extensions : empty_edid_exts;
|
||||
}
|
||||
|
||||
const struct di_edid_misc_features *di_edid_get_misc_features(const struct di_edid *edid)
|
||||
{
|
||||
return edid ? &edid->misc_features : NULL;
|
||||
}
|
||||
|
||||
const struct di_edid_cta *di_edid_ext_get_cta(const struct di_edid_ext *ext)
|
||||
{
|
||||
(void)ext;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct di_displayid *di_edid_ext_get_displayid(const struct di_edid_ext *ext)
|
||||
{
|
||||
(void)ext;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct di_cta_data_block *const *di_edid_cta_get_data_blocks(const struct di_edid_cta *cta)
|
||||
{
|
||||
(void)cta;
|
||||
return empty_cta_blocks;
|
||||
}
|
||||
|
||||
const struct di_cta_hdr_static_metadata_block *di_cta_data_block_get_hdr_static_metadata(const struct di_cta_data_block *block)
|
||||
{
|
||||
(void)block;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct di_cta_colorimetry_block *di_cta_data_block_get_colorimetry(const struct di_cta_data_block *block)
|
||||
{
|
||||
(void)block;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct di_displayid_data_block *const *di_displayid_get_data_blocks(const struct di_displayid *displayid)
|
||||
{
|
||||
(void)displayid;
|
||||
return empty_displayid_blocks;
|
||||
}
|
||||
|
||||
const struct di_displayid_display_params *di_displayid_data_block_get_display_params(const struct di_displayid_data_block *block)
|
||||
{
|
||||
(void)block;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct di_displayid_type_i_ii_vii_timing *const *di_displayid_data_block_get_type_i_timings(const struct di_displayid_data_block *block)
|
||||
{
|
||||
(void)block;
|
||||
return empty_timings;
|
||||
}
|
||||
|
||||
const struct di_displayid_type_i_ii_vii_timing *const *di_displayid_data_block_get_type_ii_timings(const struct di_displayid_data_block *block)
|
||||
{
|
||||
(void)block;
|
||||
return empty_timings;
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
# DEPRECATED (2026-07-09): KWin switched to real libepoxy recipe.
|
||||
# This stub remains for dependency compatibility only — remove
|
||||
# once all consumers have migrated to the real libepoxy.
|
||||
[source]
|
||||
path = "source"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
script = """
|
||||
DYNAMIC_INIT
|
||||
|
||||
mkdir -p "${COOKBOOK_STAGE}/usr/include/epoxy"
|
||||
mkdir -p "${COOKBOOK_STAGE}/usr/lib/cmake/epoxy"
|
||||
|
||||
cat > "${COOKBOOK_STAGE}/usr/include/epoxy/egl.h" << 'EOF'
|
||||
#pragma once
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
static inline int epoxy_egl_extension_supported(const char *ext) { (void)ext; return 0; }
|
||||
EOF
|
||||
|
||||
cat > "${COOKBOOK_STAGE}/usr/include/epoxy/gl.h" << 'EOF'
|
||||
#pragma once
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
static inline int epoxy_gl_version(void) { return 20; }
|
||||
static inline int epoxy_has_gl_extension(const char *ext) { (void)ext; return 0; }
|
||||
EOF
|
||||
|
||||
cat > "${COOKBOOK_STAGE}/usr/include/epoxy/glx.h" << 'EOF'
|
||||
#pragma once
|
||||
EOF
|
||||
|
||||
cat > "${COOKBOOK_STAGE}/usr/include/epoxy/gl_generated.h" << 'EOF'
|
||||
#pragma once
|
||||
EOF
|
||||
|
||||
cat > "${COOKBOOK_STAGE}/usr/include/epoxy/egl_generated.h" << 'EOF'
|
||||
#pragma once
|
||||
EOF
|
||||
|
||||
cat > stub_epoxy.c << 'CEOF'
|
||||
int epoxy_egl_extensions_string(void) { return 0; }
|
||||
int epoxy_has_egl_extension(const char *ext) { (void)ext; return 0; }
|
||||
int epoxy_gl_version(void) { return 20; }
|
||||
int epoxy_has_gl_extension(const char *ext) { (void)ext; return 0; }
|
||||
int epoxy_glx_version(void) { return 0; }
|
||||
int epoxy_has_glx_extension(const char *ext) { (void)ext; return 0; }
|
||||
CEOF
|
||||
|
||||
x86_64-unknown-redox-gcc -shared -fPIC -o "${COOKBOOK_STAGE}/usr/lib/libepoxy.so" stub_epoxy.c
|
||||
|
||||
cat > "${COOKBOOK_STAGE}/usr/lib/cmake/epoxy/epoxyConfig.cmake" << 'EOF'
|
||||
if(NOT TARGET epoxy::epoxy)
|
||||
add_library(epoxy::epoxy SHARED IMPORTED)
|
||||
set_target_properties(epoxy::epoxy PROPERTIES
|
||||
IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/../../../lib/libepoxy.so"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_LIST_DIR}/../../../include"
|
||||
)
|
||||
endif()
|
||||
set(epoxy_FOUND TRUE)
|
||||
EOF
|
||||
|
||||
cat > "${COOKBOOK_STAGE}/usr/lib/cmake/epoxy/epoxyConfigVersion.cmake" << 'EOF'
|
||||
set(PACKAGE_VERSION "1.5.10")
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
EOF
|
||||
"""
|
||||
@@ -1,53 +0,0 @@
|
||||
#TODO: reduced libudev provider — exposes a real libudev.so / UDev::UDev surface for the current KWin path via scheme:udev and udev-shim; hotplug event delivery remains bounded
|
||||
[source]
|
||||
path = "source"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
script = """
|
||||
DYNAMIC_INIT
|
||||
|
||||
mkdir -p "${COOKBOOK_STAGE}/usr/include"
|
||||
mkdir -p "${COOKBOOK_STAGE}/usr/lib/cmake/UDev"
|
||||
mkdir -p "${COOKBOOK_STAGE}/usr/lib/pkgconfig"
|
||||
|
||||
cp "${COOKBOOK_SOURCE}/include/libudev.h" "${COOKBOOK_STAGE}/usr/include/libudev.h"
|
||||
|
||||
x86_64-unknown-redox-gcc \
|
||||
-shared \
|
||||
-fPIC \
|
||||
-std=c11 \
|
||||
-Wall \
|
||||
-Wextra \
|
||||
-Wl,-soname,libudev.so \
|
||||
-I"${COOKBOOK_SOURCE}/include" \
|
||||
-o "${COOKBOOK_STAGE}/usr/lib/libudev.so" \
|
||||
"${COOKBOOK_SOURCE}/libudev.c"
|
||||
|
||||
cat > "${COOKBOOK_STAGE}/usr/lib/cmake/UDev/UDevConfig.cmake" << 'EOF'
|
||||
set(UDev_INCLUDE_DIRS "${CMAKE_CURRENT_LIST_DIR}/../../../include")
|
||||
set(UDev_LIBRARIES "${CMAKE_CURRENT_LIST_DIR}/../../../lib/libudev.so")
|
||||
set(UDev_VERSION "1.0.0")
|
||||
if(NOT TARGET UDev::UDev)
|
||||
add_library(UDev::UDev SHARED IMPORTED)
|
||||
set_target_properties(UDev::UDev PROPERTIES
|
||||
IMPORTED_LOCATION "${UDev_LIBRARIES}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${UDev_INCLUDE_DIRS}"
|
||||
)
|
||||
endif()
|
||||
set(UDev_FOUND TRUE)
|
||||
EOF
|
||||
|
||||
cat > "${COOKBOOK_STAGE}/usr/lib/pkgconfig/libudev.pc" << 'EOF'
|
||||
prefix=/usr
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: libudev
|
||||
Description: scheme-backed libudev provider for the reduced Red Bear path
|
||||
Version: 1.0.0
|
||||
Libs: -L${libdir} -ludev
|
||||
Cflags: -I${includedir}
|
||||
EOF
|
||||
"""
|
||||
@@ -1,73 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct udev;
|
||||
struct udev_device;
|
||||
struct udev_enumerate;
|
||||
struct udev_list_entry;
|
||||
struct udev_monitor;
|
||||
|
||||
#define udev_list_entry_foreach(list_entry, first_entry) \
|
||||
for ((list_entry) = (first_entry); (list_entry) != NULL; (list_entry) = udev_list_entry_get_next(list_entry))
|
||||
|
||||
struct udev *udev_new(void);
|
||||
struct udev *udev_ref(struct udev *udev);
|
||||
struct udev *udev_unref(struct udev *udev);
|
||||
|
||||
struct udev_enumerate *udev_enumerate_new(struct udev *udev);
|
||||
struct udev_enumerate *udev_enumerate_ref(struct udev_enumerate *udev_enumerate);
|
||||
struct udev_enumerate *udev_enumerate_unref(struct udev_enumerate *udev_enumerate);
|
||||
struct udev *udev_enumerate_get_udev(struct udev_enumerate *udev_enumerate);
|
||||
int udev_enumerate_add_match_subsystem(struct udev_enumerate *udev_enumerate, const char *subsystem);
|
||||
int udev_enumerate_add_match_sysname(struct udev_enumerate *udev_enumerate, const char *sysname);
|
||||
int udev_enumerate_add_match_property(struct udev_enumerate *udev_enumerate, const char *property, const char *value);
|
||||
int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate);
|
||||
int udev_enumerate_scan_subsystems(struct udev_enumerate *udev_enumerate);
|
||||
struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate);
|
||||
|
||||
struct udev_list_entry *udev_list_entry_get_next(struct udev_list_entry *list_entry);
|
||||
const char *udev_list_entry_get_name(struct udev_list_entry *list_entry);
|
||||
const char *udev_list_entry_get_value(struct udev_list_entry *list_entry);
|
||||
|
||||
struct udev_device *udev_device_ref(struct udev_device *udev_device);
|
||||
struct udev_device *udev_device_unref(struct udev_device *udev_device);
|
||||
struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath);
|
||||
struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum);
|
||||
struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname);
|
||||
struct udev *udev_device_get_udev(struct udev_device *udev_device);
|
||||
const char *udev_device_get_devnode(struct udev_device *udev_device);
|
||||
dev_t udev_device_get_devnum(struct udev_device *udev_device);
|
||||
const char *udev_device_get_action(struct udev_device *udev_device);
|
||||
const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key);
|
||||
struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device);
|
||||
struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device);
|
||||
struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_device *udev_device);
|
||||
struct udev_device *udev_device_get_parent(struct udev_device *udev_device);
|
||||
struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device, const char *subsystem, const char *devtype);
|
||||
const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr);
|
||||
const char *udev_device_get_devpath(struct udev_device *udev_device);
|
||||
const char *udev_device_get_syspath(struct udev_device *udev_device);
|
||||
const char *udev_device_get_subsystem(struct udev_device *udev_device);
|
||||
const char *udev_device_get_devtype(struct udev_device *udev_device);
|
||||
const char *udev_device_get_sysname(struct udev_device *udev_device);
|
||||
const char *udev_device_get_sysnum(struct udev_device *udev_device);
|
||||
const char *udev_device_get_driver(struct udev_device *udev_device);
|
||||
int udev_device_get_is_initialized(struct udev_device *udev_device);
|
||||
int udev_device_has_tag(struct udev_device *udev_device, const char *tag);
|
||||
|
||||
struct udev_monitor *udev_monitor_new_from_netlink(struct udev *udev, const char *name);
|
||||
struct udev_monitor *udev_monitor_ref(struct udev_monitor *udev_monitor);
|
||||
struct udev_monitor *udev_monitor_unref(struct udev_monitor *udev_monitor);
|
||||
int udev_monitor_filter_add_match_subsystem_devtype(struct udev_monitor *udev_monitor, const char *subsystem, const char *devtype);
|
||||
int udev_monitor_enable_receiving(struct udev_monitor *udev_monitor);
|
||||
int udev_monitor_get_fd(struct udev_monitor *udev_monitor);
|
||||
struct udev_device *udev_monitor_receive_device(struct udev_monitor *udev_monitor);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,56 +0,0 @@
|
||||
#TODO: libxcvt stub — provides libxcvt pkgconfig for KWin linking
|
||||
[source]
|
||||
path = "source"
|
||||
|
||||
[build]
|
||||
template = "custom"
|
||||
script = """
|
||||
DYNAMIC_INIT
|
||||
|
||||
mkdir -p "${COOKBOOK_STAGE}/usr/include"
|
||||
mkdir -p "${COOKBOOK_STAGE}/usr/lib/pkgconfig"
|
||||
|
||||
cat > "${COOKBOOK_STAGE}/usr/include/libxcvt.h" << 'EOF'
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
struct libxcvt_mode {
|
||||
uint32_t hdisplay;
|
||||
uint32_t vdisplay;
|
||||
uint32_t dotclock;
|
||||
uint32_t hsync_start;
|
||||
uint32_t hsync_end;
|
||||
uint32_t htotal;
|
||||
uint32_t vsync_start;
|
||||
uint32_t vsync_end;
|
||||
uint32_t vtotal;
|
||||
uint32_t hskew;
|
||||
uint32_t vscan;
|
||||
uint32_t vrefresh;
|
||||
uint32_t flags;
|
||||
uint32_t type;
|
||||
};
|
||||
struct libxcvt_mode *libxcvt_generate_mode(int hdisplay, int vdisplay, float vrefresh, bool reduced, bool interlaced) __attribute__((weak));
|
||||
void libxcvt_mode_list_free(struct libxcvt_mode **modes) __attribute__((weak));
|
||||
EOF
|
||||
|
||||
cat > stub_xcvt.c << 'CEOF'
|
||||
struct libxcvt_mode *libxcvt_generate_mode(int h, int v, float r, _Bool red, _Bool inter) { (void)h; (void)v; (void)r; (void)red; (void)inter; return 0; }
|
||||
void libxcvt_mode_list_free(struct libxcvt_mode **m) { (void)m; }
|
||||
CEOF
|
||||
|
||||
x86_64-unknown-redox-gcc -shared -fPIC -o "${COOKBOOK_STAGE}/usr/lib/libxcvt.so" stub_xcvt.c
|
||||
|
||||
cat > "${COOKBOOK_STAGE}/usr/lib/pkgconfig/libxcvt.pc" << 'EOF'
|
||||
prefix=/usr
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: libxcvt
|
||||
Description: libxcvt stub for Redox
|
||||
Version: 0.1.3
|
||||
Libs: -L${libdir} -lxcvt
|
||||
Cflags: -I${includedir}
|
||||
EOF
|
||||
"""
|
||||
@@ -1 +0,0 @@
|
||||
../../local/recipes/libs/lcms2-stub
|
||||
@@ -1 +0,0 @@
|
||||
../../local/recipes/libs/libdisplay-info-stub
|
||||
@@ -1 +0,0 @@
|
||||
../../local/recipes/libs/libepoxy-stub
|
||||
@@ -1 +0,0 @@
|
||||
../../local/recipes/libs/libudev-stub
|
||||
@@ -1 +0,0 @@
|
||||
../../local/recipes/libs/libxcvt-stub
|
||||
Reference in New Issue
Block a user