Function bodies 55 total
mk3_acquire_libusb function · c · L14-L29 (16 LOC)external/mk3/mk3.c
static bool mk3_acquire_libusb(void)
{
if (g_libusb_refcount == 0)
{
const int init_result = libusb_init(&g_libusb_context);
if (init_result != 0)
{
fprintf(stderr, "Failed to initialise libusb: %s\n", libusb_error_name(init_result));
return false;
}
}
++g_libusb_refcount;
return true;
}mk3_release_libusb function · c · L30-L42 (13 LOC)external/mk3/mk3.c
static void mk3_release_libusb(void)
{
if (g_libusb_refcount <= 0)
return;
--g_libusb_refcount;
if (g_libusb_refcount == 0)
{
libusb_exit(g_libusb_context);
g_libusb_context = NULL;
}
}mk3_open function · c · L43-L128 (86 LOC)external/mk3/mk3.c
mk3_t* mk3_open(void) {
libusb_device_handle* handle = NULL;
mk3_t* dev = NULL;
bool display_claimed = false;
bool hid_claimed = false;
if (!mk3_acquire_libusb())
return NULL;
handle = libusb_open_device_with_vid_pid(g_libusb_context, VENDOR_ID, PRODUCT_ID);
if (!handle) {
fprintf(stderr, "MK3 not found.\n");
goto cleanup;
}
if (libusb_kernel_driver_active(handle, HID_INTERFACE)) {
const int detach_res = libusb_detach_kernel_driver(handle, HID_INTERFACE);
if (detach_res != 0) {
fprintf(stderr, "Failed to detach kernel driver from HID interface: %s\n", libusb_error_name(detach_res));
goto cleanup;
}
}
if (libusb_claim_interface(handle, DISPLAY_INTERFACE) != 0) {
fprintf(stderr, "Failed to claim interface %d (Display)\n", DISPLAY_INTERFACE);
goto cleanup;
}
display_claimed = true;
if (libusb_claim_interface(handle, HID_INTERFACE) != 0) {
mk3_open_display function · c · L129-L191 (63 LOC)external/mk3/mk3.c
mk3_t* mk3_open_display(void) {
libusb_device_handle* handle = NULL;
mk3_t* dev = NULL;
bool display_claimed = false;
if (!mk3_acquire_libusb())
return NULL;
handle = libusb_open_device_with_vid_pid(g_libusb_context, VENDOR_ID, PRODUCT_ID);
if (!handle) {
fprintf(stderr, "MK3 not found.\n");
goto cleanup;
}
if (libusb_claim_interface(handle, DISPLAY_INTERFACE) != 0) {
fprintf(stderr, "Failed to claim interface %d (Display)\n", DISPLAY_INTERFACE);
goto cleanup;
}
display_claimed = true;
dev = calloc(1, sizeof(mk3_t));
if (!dev)
goto cleanup;
dev->handle = handle;
dev->disable_partial_rendering = false;
dev->clear_frame_buffer = calloc(WIDTH * HEIGHT, sizeof(uint16_t));
if (!dev->clear_frame_buffer)
goto cleanup;
for (int i = 0; i < 2; i++) {
dev->last_frame[i] = calloc(WIDTH * HEIGHT, sizeof(uint16_t));
if (!dev->last_frame[i])
gmk3_close function · c · L192-L209 (18 LOC)external/mk3/mk3.c
void mk3_close(mk3_t* dev) {
if (!dev) return;
for (int i = 0; i < 2; i++) {
free(dev->last_frame[i]);
dev->last_frame[i] = NULL;
}
free(dev->clear_frame_buffer);
dev->clear_frame_buffer = NULL;
libusb_release_interface(dev->handle, DISPLAY_INTERFACE);
libusb_release_interface(dev->handle, HID_INTERFACE);
libusb_close(dev->handle);
mk3_release_libusb();
free(dev);
}mk3_close_display function · c · L210-L226 (17 LOC)external/mk3/mk3.c
void mk3_close_display(mk3_t* dev) {
if (!dev) return;
for (int i = 0; i < 2; i++) {
free(dev->last_frame[i]);
dev->last_frame[i] = NULL;
}
free(dev->clear_frame_buffer);
dev->clear_frame_buffer = NULL;
libusb_release_interface(dev->handle, DISPLAY_INTERFACE);
libusb_close(dev->handle);
mk3_release_libusb();
free(dev);
}mk3_display_disable_partial_rendering function · c · L227-L231 (5 LOC)external/mk3/mk3.c
void mk3_display_disable_partial_rendering(mk3_t* dev, bool disable) {
if (!dev) return;
dev->disable_partial_rendering = disable;
}Repobility · MCP-ready · https://repobility.com
_mk3_display_draw_full_frame_internal function · c · L14-L48 (35 LOC)external/mk3/mk3_display.c
static int _mk3_display_draw_full_frame_internal(mk3_t* dev, int screen_index, const uint16_t* pixels) {
uint8_t* frame = malloc(FRAME_SIZE);
if (!frame) return -1;
// Header
memset(frame, 0, 16);
frame[0] = 0x84;
frame[1] = 0x00;
frame[2] = screen_index;
frame[3] = 0x60;
frame[8] = 0x00; frame[9] = 0x00; // X start
frame[10] = 0x00; frame[11] = 0x00; // Y start
frame[12] = (WIDTH >> 8); frame[13] = (WIDTH & 0xFF);
frame[14] = (HEIGHT >> 8); frame[15] = (HEIGHT & 0xFF);
int half = FRAME_PIXELS / 2;
frame[16] = 0x00;
frame[17] = (half >> 16) & 0xFF;
frame[18] = (half >> 8) & 0xFF;
frame[19] = half & 0xFF;
uint16_t* out = (uint16_t*)(frame + 20);
for (int i = 0; i < FRAME_PIXELS; i++) {
out[i] = htobe16(pixels[i]);
}
frame[FRAME_SIZE - 8] = 0x03;
frame[FRAME_SIZE - 4] = 0x40;
int transferred = 0;
int res = libusb_bulk_transfer(dev->handle, DISPLAY_ENDPOINT, frame, FRAME_SIZE, &tmk3_display_draw_partial function · c · L49-L98 (50 LOC)external/mk3/mk3_display.c
int mk3_display_draw_partial(mk3_t* dev, int screen_index, int x, int y, int w, int h, const uint16_t* pixels) {
if (!dev || !pixels || w <= 0 || h <= 0) return -1;
const int region_pixels = w * h;
const int frame_size = 16 + 4 + region_pixels * 2 + 8;
uint8_t* frame = malloc(frame_size);
if (!frame) return -1;
// Header
memset(frame, 0, 16);
frame[0] = 0x84;
frame[1] = 0x00;
frame[2] = screen_index;
frame[3] = 0x60;
frame[8] = (x >> 8); frame[9] = (x & 0xFF);
frame[10] = (y >> 8); frame[11] = (y & 0xFF);
frame[12] = (w >> 8); frame[13] = (w & 0xFF);
frame[14] = (h >> 8); frame[15] = (h & 0xFF);
// Command
int half = region_pixels / 2;
frame[16] = 0x00;
frame[17] = (half >> 16) & 0xFF;
frame[18] = (half >> 8) & 0xFF;
frame[19] = half & 0xFF;
// Pixel data
uint16_t* out = (uint16_t*)(frame + 20);
for (int i = 0; i < region_pixels; i++) {
out[i] = htobe16(pixels[i]);
}
mk3_display_draw function · c · L99-L167 (69 LOC)external/mk3/mk3_display.c
int mk3_display_draw(mk3_t* dev, int screen_index, const uint16_t* pixels) {
if (!dev || !pixels) return -1;
uint16_t* last = dev->last_frame[screen_index];
bool* has_last = &dev->has_last_frame[screen_index];
// TODO: Fix partial rendering bug that occurs when selecting pads in DAW sampler
// When disable_partial_rendering is true, always do full screen updates
if (dev->disable_partial_rendering) {
// Force full screen update by skipping diffing logic
int result = _mk3_display_draw_full_frame_internal(dev, screen_index, pixels);
// Update last frame for consistency only if transfer was successful
if (result == 0) {
memcpy(last, pixels, WIDTH * HEIGHT * sizeof(uint16_t));
*has_last = true;
}
return result;
}
if (*has_last) {
int min_x = WIDTH, max_x = -1;
int min_y = HEIGHT, max_y = -1;
for (int y = 0; y < HEIGHT; y++) {
for (int x = 0; x < WImk3_display_clear function · c · L168-L185 (18 LOC)external/mk3/mk3_display.c
int mk3_display_clear(mk3_t* dev, int screen_index, uint16_t color) {
if (!dev)
return -1;
if (dev->clear_frame_buffer == NULL)
{
dev->clear_frame_buffer = calloc(WIDTH * HEIGHT, sizeof(uint16_t));
if (dev->clear_frame_buffer == NULL)
return -1;
}
for (int i = 0; i < WIDTH * HEIGHT; i++) {
dev->clear_frame_buffer[i] = color;
}
return mk3_display_draw(dev, screen_index, dev->clear_frame_buffer);
}knob_descriptor_count function · c · L65-L68 (4 LOC)external/mk3/mk3_input.c
static size_t knob_descriptor_count(void) {
return sizeof(knob_descriptors) / sizeof(knob_descriptors[0]);
}compute_knob_delta function · c · L69-L78 (10 LOC)external/mk3/mk3_input.c
static int16_t compute_knob_delta(uint16_t previous, uint16_t current) {
int16_t delta = (int16_t)(current - previous);
if (delta > 2048) {
delta -= 4096;
} else if (delta < -2048) {
delta += 4096;
}
return delta;
}process_knob_values function · c · L79-L108 (30 LOC)external/mk3/mk3_input.c
static void process_knob_values(mk3_t* dev, const uint8_t* buffer, int len) {
const size_t count = knob_descriptor_count();
for (size_t i = 0; i < count; i++) {
const mk3_knob_descriptor_t* desc = &knob_descriptors[i];
if (desc->msb_addr >= len || desc->lsb_addr >= len) {
continue;
}
uint16_t current_value = ((uint16_t)buffer[desc->msb_addr] << 8) | buffer[desc->lsb_addr];
if (!dev->knob_initialized[i]) {
dev->knob_values[i] = current_value;
dev->knob_initialized[i] = true;
continue;
}
if (current_value == dev->knob_values[i]) {
continue;
}
int16_t delta = compute_knob_delta(dev->knob_values[i], current_value);
dev->knob_values[i] = current_value;
if (dev->knob_callback) {
dev->knob_callback(desc->name, delta, current_value, dev->knob_callback_userdata);
}
}
}process_stepper function · c · L109-L137 (29 LOC)external/mk3/mk3_input.c
static void process_stepper(mk3_t* dev, const uint8_t* buffer, int len) {
if (STEPPER_ADDR >= len) {
return;
}
uint8_t new_position = buffer[STEPPER_ADDR] & 0x0F;
if (!dev->stepper_initialized) {
dev->stepper_position = new_position;
dev->stepper_initialized = true;
return;
}
if (new_position == dev->stepper_position) {
return;
}
bool jump_backward = (dev->stepper_position == 0x00 && new_position == 0x0F);
bool jump_forward = (dev->stepper_position == 0x0F && new_position == 0x00);
bool increment = ((dev->stepper_position < new_position) && !jump_backward) || jump_forward;
int8_t direction = increment ? 1 : -1;
dev->stepper_position = new_position;
if (dev->stepper_callback) {
dev->stepper_callback(direction, new_position, dev->stepper_callback_userdata);
}
}Want this analysis on your repo? https://repobility.com/scan/
process_report_01_inputs function · c · L138-L176 (39 LOC)external/mk3/mk3_input.c
static void process_report_01_inputs(mk3_t* dev, const uint8_t* buffer, int len) {
// Ensure last_input_buffer is also from a 0x01 report for correct comparison
bool last_buffer_was_button_report = (dev->last_input_buffer[0] == 0x01);
for (int i = 0; i < mk3_buttons_count; i++) {
const mk3_button_t* btn = &mk3_buttons[i];
// btn->addr is the index in the full buffer (e.g., JSON addr 1 is buffer[1]).
// Button addresses should be > 0, as buffer[0] is the report ID.
if (btn->addr == 0 || btn->addr >= len) continue;
bool now_pressed = (buffer[btn->addr] & btn->mask) != 0;
bool was_pressed = false;
if (last_buffer_was_button_report &&
btn->addr > 0 && btn->addr < dev->last_report_01_len) {
was_pressed = (dev->last_input_buffer[btn->addr] & btn->mask) != 0;
}
if (now_pressed && !was_pressed) {
// printf("🔘 Button Pressed: %s\n", btn->name); // Debug print
process_report_02_pads function · c · L177-L215 (39 LOC)external/mk3/mk3_input.c
static void process_report_02_pads(mk3_t* dev, const uint8_t* buffer, int len) {
int offset = PAD_DATA_START_OFFSET;
for (int i_rep = 0; i_rep < PAD_MAX_REPEATED_ENTRIES; i_rep++, offset += PAD_ENTRY_LENGTH) {
if (offset + PAD_ENTRY_LENGTH > len) break; // Not enough data for a full entry
uint8_t pad_hw_index = buffer[offset];
// uint8_t weird_nibble = (buffer[offset + 1] & 0xF0) >> 4; // For debugging, usually 0x4 or 0x2/0x3 on release
// bool is_valid_entry = (buffer[offset + 1] & 0xF0) != 0; // Check "weird" nibble
if (pad_hw_index == 0 && i_rep != 0) { // End-of-packet marker (unless it's the first entry for pad 0)
break;
}
if (pad_hw_index >= PAD_COUNT) continue; // Invalid hardware pad index
// Map hardware index to physical pad number (1-16)
uint8_t physical_pad_number = mk3_pad_hw_to_physical_map[pad_hw_index];
// Convert to 0-indexed for arrays
uint8_t physical_pad_amk3_input_poll function · c · L216-L256 (41 LOC)external/mk3/mk3_input.c
int mk3_input_poll(mk3_t* dev) {
if (!dev) return -1;
uint8_t buffer[HID_INPUT_PACKET_SIZE];
int transferred = 0;
int res = libusb_interrupt_transfer(dev->handle, HID_INPUT_ENDPOINT, buffer, sizeof(buffer), &transferred, 100);
if (res == LIBUSB_SUCCESS && transferred > 0) {
// --- RAW PACKET DEBUG (Commented out for cleaner output) ---
/*
printf("RAW HID (len %2d, ID 0x%02X): ", transferred, buffer[0]);
for (int k = 0; k < transferred; k++) {
printf("%02X ", buffer[k]);
}
printf("\n");
*/
if (transferred < 1) { // Should not happen if transferred > 0, but good practice
return 0;
}
uint8_t report_id = buffer[0];
if (report_id == 0x01) { // Buttons, Knobs, Stepper, Touchstrips
process_report_01_inputs(dev, buffer, transferred);
return 1; // Indicate button report processed
} else if (report_id == PAD_REPORT_ID) { // Padmk3_input_set_pad_callback function · c · L257-L262 (6 LOC)external/mk3/mk3_input.c
void mk3_input_set_pad_callback(mk3_t* dev, mk3_pad_callback_t callback, void* userdata) {
if (!dev) return;
dev->pad_callback = callback;
dev->pad_callback_userdata = userdata;
}mk3_input_set_button_callback function · c · L263-L267 (5 LOC)external/mk3/mk3_input.c
void mk3_input_set_button_callback(mk3_t* dev, mk3_button_callback_t callback, void* userdata) {
if (!dev) return;
dev->button_callback = callback;
dev->button_callback_userdata = userdata;
}mk3_input_set_knob_callback function · c · L268-L273 (6 LOC)external/mk3/mk3_input.c
void mk3_input_set_knob_callback(mk3_t* dev, mk3_knob_callback_t callback, void* userdata) {
if (!dev) return;
dev->knob_callback = callback;
dev->knob_callback_userdata = userdata;
}mk3_input_set_stepper_callback function · c · L274-L279 (6 LOC)external/mk3/mk3_input.c
void mk3_input_set_stepper_callback(mk3_t* dev, mk3_stepper_callback_t callback, void* userdata) {
if (!dev) return;
dev->stepper_callback = callback;
dev->stepper_callback_userdata = userdata;
}find_led_def function · c · L9-L16 (8 LOC)external/mk3/mk3_output.c
static const mk3_led_definition_t* find_led_def(const char* led_name) {
for (int i = 0; i < mk3_leds_count; ++i) {
if (strcmp(mk3_leds[i].name, led_name) == 0) {
return &mk3_leds[i];
}
}
return NULL;
}Repobility analyzer · published findings · https://repobility.com
send_output_report function · c · L19-L45 (27 LOC)external/mk3/mk3_output.c
static int send_output_report(mk3_t* dev, uint8_t report_id, uint8_t* buffer, int length) {
if (!dev || !dev->handle) return -1;
// Ensure buffer[0] is the report_id, though it should already be set.
buffer[0] = report_id;
int transferred = 0;
// Use libusb_control_transfer for SetReport on HID devices as per HID spec
// Or libusb_interrupt_transfer if the device uses an explicit OUT endpoint for reports
// For MK3, HID_OUTPUT_ENDPOINT (0x03) is an interrupt OUT endpoint.
int res = libusb_interrupt_transfer(dev->handle,
HID_OUTPUT_ENDPOINT,
buffer,
length,
&transferred,
100); // 100ms timeout
if (res != LIBUSB_SUCCESS) {
fprintf(stderr, "Failed to send LED report 0x%02X: %s\n", report_id, libusb_error_name(res));
return -1;
}
imk3_led_set_brightness function · c · L46-L68 (23 LOC)external/mk3/mk3_output.c
int mk3_led_set_brightness(mk3_t* dev, const char* led_name, uint8_t brightness) {
if (!dev) return -1;
const mk3_led_definition_t* led_def = find_led_def(led_name);
if (!led_def) {
fprintf(stderr, "LED not found: %s\n", led_name);
return -1;
}
if (led_def->type != MK3_LED_TYPE_MONO) {
fprintf(stderr, "LED %s is not a monochromatic LED.\n", led_name);
return -1;
}
uint8_t val = brightness > 63 ? 63 : brightness; // Cap at 63 for MK3
if (led_def->report_id == 0x80) {
dev->output_report_80_buffer[led_def->addr] = val;
return send_output_report(dev, 0x80, dev->output_report_80_buffer, sizeof(dev->output_report_80_buffer));
}
// Add other report IDs if mono LEDs exist there
fprintf(stderr, "LED %s has unhandled report ID 0x%02X for mono type.\n", led_name, led_def->report_id);
return -1;
}mk3_led_set_indexed_color function · c · L69-L93 (25 LOC)external/mk3/mk3_output.c
int mk3_led_set_indexed_color(mk3_t* dev, const char* led_name, uint8_t color_index) {
if (!dev) return -1;
const mk3_led_definition_t* led_def = find_led_def(led_name);
if (!led_def) {
fprintf(stderr, "LED not found: %s\n", led_name);
return -1;
}
if (led_def->type != MK3_LED_TYPE_INDEXED) {
fprintf(stderr, "LED %s is not an indexed color LED.\n", led_name);
return -1;
}
uint8_t val = color_index > 71 ? 0 : color_index; // Cap at 71 (typical max index)
if (led_def->report_id == 0x80) {
dev->output_report_80_buffer[led_def->addr] = val;
return send_output_report(dev, 0x80, dev->output_report_80_buffer, sizeof(dev->output_report_80_buffer));
} else if (led_def->report_id == 0x81) {
dev->output_report_81_buffer[led_def->addr] = val;
return send_output_report(dev, 0x81, dev->output_report_81_buffer, sizeof(dev->output_report_81_buffer));
}
fprintf(stderr, "LED %s has unhandled resetup_terminal_nonblocking function · c · L36-L43 (8 LOC)external/mpi-tools/audio_cli/audio_cli.c
static void setup_terminal_nonblocking(void) {
tcgetattr(STDIN_FILENO, &old_tio);
new_tio = old_tio;
new_tio.c_lflag &= (~ICANON & ~ECHO);
new_tio.c_cc[VMIN] = 0;
new_tio.c_cc[VTIME] = 0;
tcsetattr(STDIN_FILENO, TCSANOW, &new_tio);
}reset_terminal function · c · L44-L47 (4 LOC)external/mpi-tools/audio_cli/audio_cli.c
static void reset_terminal(void) {
tcsetattr(STDIN_FILENO, TCSANOW, &old_tio);
}process_with_wav function · c · L51-L58 (8 LOC)external/mpi-tools/audio_cli/audio_cli.c
static void process_with_wav(audio_node_t* node, float** bufs, int frames) {
if (original_process) {
original_process(node, bufs, frames);
}
if (g_sndfile && bufs && bufs[0]) {
sf_writef_float(g_sndfile, bufs[0], frames);
}
}sigint_handler function · c · L61-L64 (4 LOC)external/mpi-tools/audio_cli/audio_cli.c
static void sigint_handler(int sig) {
(void)sig;
g_keep_main_loop_running = false;
}backend_runner function · c · L67-L72 (6 LOC)external/mpi-tools/audio_cli/audio_cli.c
static void* backend_runner(void* arg) {
runner_t* r = (runner_t*)arg;
audio_backend_run(r->backend);
r->running = false;
return NULL;
}Same scanner, your repo: https://repobility.com — Repobility
main function · c · L73-L294 (222 LOC)external/mpi-tools/audio_cli/audio_cli.c
int main(int argc, char* argv[]) {
float freq = 440.0f;
int duration = 5;
const char* wav_output_path = NULL;
const char* sampler_folder = NULL;
const char* dsp_plugin_path = NULL;
// Parse command-line arguments
for (int i = 1; i < argc; ++i) {
if (strcmp(argv[i], "--sine") == 0 && i+1 < argc) {
freq = atof(argv[++i]);
} else if (strcmp(argv[i], "--time") == 0 && i+1 < argc) {
duration = atoi(argv[++i]);
} else if (strcmp(argv[i], "--out") == 0 && i+1 < argc) {
wav_output_path = argv[++i];
} else if (strcmp(argv[i], "--sampler") == 0 && i+1 < argc) {
sampler_folder = argv[++i];
} else if (strcmp(argv[i], "--dsp") == 0 && i+1 < argc) {
dsp_plugin_path = argv[++i];
}
}
// Print mode info
if (sampler_folder) {
printf("🎧 Sampler Mode: %s\n", sampler_folder);
} else {
printf("🔊 Sine Mode: draw_text_rgb565 function · c · L14-L44 (31 LOC)external/mpi-tools/mk3_cli/mk3_cli.c
void draw_text_rgb565(uint16_t* buf, const char* msg, int x, int y) {
FT_Library ft;
FT_Face face;
if (FT_Init_FreeType(&ft)) return;
if (FT_New_Face(ft, "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 0, &face)) return;
FT_Set_Pixel_Sizes(face, 0, 24);
int pen_x = x, pen_y = y;
for (size_t i = 0; i < strlen(msg); i++) {
if (FT_Load_Char(face, msg[i], FT_LOAD_RENDER)) continue;
FT_GlyphSlot g = face->glyph;
for (int row = 0; row < g->bitmap.rows; row++) {
for (int col = 0; col < g->bitmap.width; col++) {
int px = pen_x + g->bitmap_left + col;
int py = pen_y - g->bitmap_top + row;
if (px < 0 || py < 0 || px >= WIDTH || py >= HEIGHT) continue;
uint8_t val = g->bitmap.buffer[row * g->bitmap.pitch + col];
uint8_t r = val, g_ = val, b = val;
buf[py * WIDTH + px] = ((r & 0xF8) << 8) | ((g_ & 0xFC) << 3) | (b >> 3);
main function · c · L45-L136 (92 LOC)external/mpi-tools/mk3_cli/mk3_cli.c
int main(int argc, char** argv) {
const char* msg = NULL;
int target = 0; // default: left
int clear_display = 0;
int use_pipe = 0;
int loop_fps = 0;
int disable_partial_rendering = 0;
for (int i = 1; i < argc; i++) {
if (!strcmp(argv[i], "--text") && i + 1 < argc) {
msg = argv[++i];
} else if (!strcmp(argv[i], "--target") && i + 1 < argc) {
const char* t = argv[++i];
if (!strcmp(t, "right")) target = 1;
else if (!strcmp(t, "both")) target = 2;
else if (!strcmp(t, "left")) target = 0;
else {
fprintf(stderr, "Unknown target: %s\n", t);
return 1;
}
} else if (!strcmp(argv[i], "--clear-display")) {
clear_display = 1;
} else if (!strcmp(argv[i], "--pipe")) {
use_pipe = 1;
} else if (!strcmp(argv[i], "--loop") && i + 1 < argc) {
loop_fps = atoi(argv[++i]);
if (try_open_card function · c · L23-L60 (38 LOC)screen-daemon/capture_drm.c
static int try_open_card(const char* path) {
int fd = open(path, O_RDWR);
if (fd < 0) return -1;
/* Need master or at least universal planes cap */
if (drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) < 0) {
/* Try without — some drivers support getPlaneResources without the cap */
}
/* Check if this card has any planes (i.e., is a display controller) */
drmModePlaneResPtr planes = drmModeGetPlaneResources(fd);
if (!planes) {
fprintf(stderr, "capture_drm: %s — no plane resources\n", path);
close(fd);
return -1;
}
/* Check if any plane has an active framebuffer */
int has_active = 0;
for (uint32_t i = 0; i < planes->count_planes; i++) {
drmModePlanePtr p = drmModeGetPlane(fd, planes->planes[i]);
if (p) {
if (p->fb_id != 0) has_active = 1;
drmModeFreePlane(p);
}
if (has_active) break;
}
drmModeFreePlaneResources(planes);
if (has_accapture_open function · c · L61-L91 (31 LOC)screen-daemon/capture_drm.c
capture_ctx_t* capture_open(int width, int height) {
(void)width;
(void)height;
capture_ctx_t* ctx = calloc(1, sizeof(*ctx));
if (!ctx) return NULL;
ctx->drm_fd = -1;
ctx->prev_map = NULL;
ctx->prev_map_size = 0;
ctx->prev_prime_fd = -1;
/* Try all available DRM cards */
const char* cards[] = {"/dev/dri/card0", "/dev/dri/card1", "/dev/dri/card2", NULL};
for (int i = 0; cards[i]; i++) {
int fd = try_open_card(cards[i]);
if (fd >= 0) {
ctx->drm_fd = fd;
break;
}
}
if (ctx->drm_fd < 0) {
fprintf(stderr, "capture_drm: no usable DRM card found\n");
free(ctx);
return NULL;
}
return ctx;
}capture_frame function · c · L92-L169 (78 LOC)screen-daemon/capture_drm.c
const uint8_t* capture_frame(capture_ctx_t* ctx) {
if (!ctx || ctx->drm_fd < 0) return NULL;
/* Release previous mapping */
if (ctx->prev_map) {
munmap(ctx->prev_map, ctx->prev_map_size);
ctx->prev_map = NULL;
}
if (ctx->prev_prime_fd >= 0) {
close(ctx->prev_prime_fd);
ctx->prev_prime_fd = -1;
}
/* Find active plane with a framebuffer */
drmModePlaneResPtr plane_res = drmModeGetPlaneResources(ctx->drm_fd);
if (!plane_res) {
fprintf(stderr, "capture_drm: drmModeGetPlaneResources: %m\n");
return NULL;
}
uint32_t active_fb_id = 0;
for (uint32_t i = 0; i < plane_res->count_planes; i++) {
drmModePlanePtr plane = drmModeGetPlane(ctx->drm_fd, plane_res->planes[i]);
if (plane && plane->fb_id) {
active_fb_id = plane->fb_id;
drmModeFreePlane(plane);
break;
}
if (plane) drmModeFreePlane(plane);
}
drmModeFreePlaneResources(pcapture_bpp function · c · L170-L174 (5 LOC)screen-daemon/capture_drm.c
int capture_bpp(capture_ctx_t* ctx) {
(void)ctx;
return 4; /* XRGB8888 */
}capture_stride function · c · L175-L179 (5 LOC)screen-daemon/capture_drm.c
int capture_stride(capture_ctx_t* ctx) {
(void)ctx;
return 0; /* unknown — main.c falls back to width * bpp */
}Repobility · MCP-ready · https://repobility.com
capture_close function · c · L180-L187 (8 LOC)screen-daemon/capture_drm.c
void capture_close(capture_ctx_t* ctx) {
if (!ctx) return;
if (ctx->prev_map) munmap(ctx->prev_map, ctx->prev_map_size);
if (ctx->prev_prime_fd >= 0) close(ctx->prev_prime_fd);
if (ctx->drm_fd >= 0) close(ctx->drm_fd);
free(ctx);
}capture_open function · c · L18-L56 (39 LOC)screen-daemon/capture_linuxfb.c
capture_ctx_t* capture_open(int width, int height) {
(void)width;
(void)height;
capture_ctx_t* ctx = calloc(1, sizeof(*ctx));
if (!ctx) return NULL;
ctx->fd = open("/dev/fb0", O_RDONLY);
if (ctx->fd < 0) {
perror("capture_linuxfb: open /dev/fb0");
free(ctx);
return NULL;
}
if (ioctl(ctx->fd, FBIOGET_VSCREENINFO, &ctx->vinfo) < 0) {
perror("capture_linuxfb: FBIOGET_VSCREENINFO");
close(ctx->fd);
free(ctx);
return NULL;
}
ctx->fb_size = (size_t)ctx->vinfo.xres_virtual
* ctx->vinfo.yres_virtual
* (ctx->vinfo.bits_per_pixel / 8);
ctx->fb_ptr = mmap(NULL, ctx->fb_size, PROT_READ, MAP_SHARED, ctx->fd, 0);
if (ctx->fb_ptr == MAP_FAILED) {
perror("capture_linuxfb: mmap");
close(ctx->fd);
free(ctx);
return NULL;
}
printf("capture_linuxfb: %ux%u @ %ubpp\n",
ctx->vinfo.xres, ctx->vinfo.yres, ctx->vinfo.bcapture_frame function · c · L57-L63 (7 LOC)screen-daemon/capture_linuxfb.c
const uint8_t* capture_frame(capture_ctx_t* ctx) {
if (!ctx) return NULL;
/* The mmap is MAP_SHARED — the kernel updates the mapping live, so we
simply return the pointer to the current framebuffer contents. */
return ctx->fb_ptr;
}capture_bpp function · c · L64-L68 (5 LOC)screen-daemon/capture_linuxfb.c
int capture_bpp(capture_ctx_t* ctx) {
if (!ctx) return 0;
return (int)(ctx->vinfo.bits_per_pixel / 8);
}capture_stride function · c · L69-L73 (5 LOC)screen-daemon/capture_linuxfb.c
int capture_stride(capture_ctx_t* ctx) {
if (!ctx) return 0;
return (int)(ctx->vinfo.xres * ctx->vinfo.bits_per_pixel / 8);
}capture_close function · c · L74-L82 (9 LOC)screen-daemon/capture_linuxfb.c
void capture_close(capture_ctx_t* ctx) {
if (!ctx) return;
if (ctx->fb_ptr && ctx->fb_ptr != MAP_FAILED)
munmap(ctx->fb_ptr, ctx->fb_size);
if (ctx->fd >= 0)
close(ctx->fd);
free(ctx);
}capture_open function · c · L19-L51 (33 LOC)screen-daemon/capture_x11.c
capture_ctx_t* capture_open(int width, int height) {
(void)width;
(void)height;
capture_ctx_t* ctx = calloc(1, sizeof(*ctx));
if (!ctx) return NULL;
ctx->dpy = XOpenDisplay(NULL);
if (!ctx->dpy) {
fprintf(stderr, "capture_x11: cannot open display (is DISPLAY set?)\n");
free(ctx);
return NULL;
}
Screen* screen = DefaultScreenOfDisplay(ctx->dpy);
ctx->root = DefaultRootWindow(ctx->dpy);
ctx->width = screen->width;
ctx->height = screen->height;
ctx->bpp = 4;
ctx->stride = ctx->width * 4;
ctx->image = NULL;
/* IncludeInferiors: when we XGetImage the root window, include all
child windows' content — this is how scrot works */
XSetSubwindowMode(ctx->dpy, DefaultGC(ctx->dpy, DefaultScreen(ctx->dpy)),
IncludeInferiors);
fprintf(stderr, "capture_x11: display %dx%d depth=%d\n",
ctx->width, ctx->height, DefaultDepthOfScreen(screen));
return ctx;
}capture_frame function · c · L52-L69 (18 LOC)screen-daemon/capture_x11.c
const uint8_t* capture_frame(capture_ctx_t* ctx) {
if (!ctx || !ctx->dpy) return NULL;
if (ctx->image) {
XDestroyImage(ctx->image);
ctx->image = NULL;
}
ctx->image = XGetImage(ctx->dpy, ctx->root,
0, 0, ctx->width, ctx->height,
AllPlanes, ZPixmap);
if (!ctx->image) return NULL;
ctx->bpp = ctx->image->bits_per_pixel / 8;
ctx->stride = ctx->image->bytes_per_line;
return (const uint8_t*)ctx->image->data;
}Want this analysis on your repo? https://repobility.com/scan/
capture_bpp function · c · L70-L73 (4 LOC)screen-daemon/capture_x11.c
int capture_bpp(capture_ctx_t* ctx) {
return ctx ? ctx->bpp : 0;
}capture_stride function · c · L74-L77 (4 LOC)screen-daemon/capture_x11.c
int capture_stride(capture_ctx_t* ctx) {
return ctx ? ctx->stride : 0;
}capture_close function · c · L78-L84 (7 LOC)screen-daemon/capture_x11.c
void capture_close(capture_ctx_t* ctx) {
if (!ctx) return;
if (ctx->image) XDestroyImage(ctx->image);
if (ctx->dpy) XCloseDisplay(ctx->dpy);
free(ctx);
}page 1 / 2next ›