From 3510cd7384d9cd0c2eee70cd879b3af7b9ade6bd Mon Sep 17 00:00:00 2001 From: Khoa Vo Date: Fri, 26 Jun 2026 10:05:22 +0700 Subject: [PATCH] fix: correct XRecordRange layout (32 bytes, device_events at offset 18) - XRecordRange is 32 bytes: core_requests(0), core_replies(2), ext_requests(4), ext_replies(10), delivered_events(16), device_events(18), errors(20), client_started(24), client_died(28) - XRecordClientSpec is XID = unsigned long (8 bytes), not int (4 bytes) - Use XRecordAllClients=3 instead of XRecordCurrentClients=1 --- protocol/src/x11_capture.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/protocol/src/x11_capture.rs b/protocol/src/x11_capture.rs index c11794b..3a70499 100644 --- a/protocol/src/x11_capture.rs +++ b/protocol/src/x11_capture.rs @@ -46,14 +46,11 @@ struct X11Lib { x_free: unsafe extern "C" fn(*mut c_void) -> c_int, } -// XRecordRange - must match C layout exactly -// C layout: { int client_spec; struct { u8 first; u8 last; } device_events; ... } +// XRecordRange: 32 bytes total +// device_events is at offset 18 (XRecordRange8: first=offset 18, last=offset 19) #[repr(C)] struct XRecordRange { - client_spec: c_int, - device_events_first: u8, - device_events_last: u8, - _pad: [u8; 250], + _bytes: [u8; 32], } type XRecordCallback = unsafe extern "C" fn(*mut c_void, *mut XRecordInterceptData); @@ -332,18 +329,20 @@ impl X11Capture { (lib.x_close_display)(display); return None; } - // Set range: KeyPress (2) through KeyRelease (3) - (*range).device_events_first = KEY_PRESS as u8; - (*range).device_events_last = KEY_RELEASE as u8; + // Set range: device_events at offset 18 + // XRecordRange8: first byte, last byte + (*range)._bytes[18] = KEY_PRESS as u8; // device_events.first + (*range)._bytes[19] = KEY_RELEASE as u8; // device_events.last eprintln!("[vietc] X11Capture: range set (KeyPress={}, KeyRelease={})", KEY_PRESS, KEY_RELEASE); // Create XRecord context - let mut spec: c_int = 1; // XRecordAllClients = 1 + // XRecordClientSpec is XID = unsigned long (8 bytes on x86_64) + let mut spec: u64 = 3; // XRecordAllClients = 3 let mut range_ptr: *mut XRecordRange = range; let ctx = (lib.x_record_create_context)( display, 0, // own_client - &mut spec, // clients + &mut spec as *mut u64 as *mut c_int, // client_spec (pointer to unsigned long) 1, // nclients &mut range_ptr, // ranges (pointer to array of range pointers) 1, // nranges