功能:接入Linux原生光标并完善设备接入工具
这个提交包含在:
1 父节点
a14f028402
当前提交
a47968496e
92 个文件已更改
+3090
-22
没有与搜索条件相匹配的文件
@@ -0,0 +1,54 @@
|
||||
/* Linux/glibc X11 capture adapter. Only preload into a leased Sunshine process.
|
||||
* Sunshine resolves XFixesGetCursorImage with dlsym(), so a plain symbol
|
||||
* interposer is insufficient. No system library or desktop theme is replaced.
|
||||
* ABI matches XFixesCursorImage from the Xorg Xfixes.h public header.
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
#include <stddef.h>
|
||||
extern void *dlvsym(void *, const char *, const char *);
|
||||
extern char *getenv(const char *);
|
||||
extern int strcmp(const char *, const char *);
|
||||
extern void abort(void);
|
||||
extern int open(const char *, int, ...);
|
||||
extern long write(int, const void *, unsigned long);
|
||||
extern int close(int);
|
||||
typedef struct {
|
||||
short x, y;
|
||||
unsigned short width, height, xhot, yhot;
|
||||
unsigned long serial;
|
||||
unsigned long *pixels;
|
||||
unsigned long atom;
|
||||
const char *name;
|
||||
} CursorImage;
|
||||
typedef void *(*Lookup)(void *, const char *);
|
||||
typedef CursorImage *(*GetImage)(void *);
|
||||
static GetImage real_image;
|
||||
|
||||
static CursorImage *capture_image(void *display) {
|
||||
GetImage fn = __atomic_load_n(&real_image, __ATOMIC_ACQUIRE);
|
||||
if (!fn) abort();
|
||||
CursorImage *image = fn(display);
|
||||
if (image && image->pixels) {
|
||||
unsigned long n = (unsigned long)image->width * image->height;
|
||||
if (n > 1048576) abort();
|
||||
for (unsigned long i = 0; i < n; ++i) image->pixels[i] = 0;
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
void *dlsym(void *handle, const char *name) {
|
||||
Lookup lookup = (Lookup)dlvsym((void *)-1L, "dlsym", "GLIBC_2.2.5");
|
||||
if (!lookup) abort();
|
||||
void *result = lookup(handle, name);
|
||||
if (result && getenv("VDI_CURSOR_LEASE") &&
|
||||
strcmp(name, "XFixesGetCursorImage") == 0) {
|
||||
__atomic_store_n(&real_image, (GetImage)result, __ATOMIC_RELEASE);
|
||||
const char *receipt = getenv("VDI_CURSOR_RECEIPT");
|
||||
if (receipt) {
|
||||
int fd = open(receipt, 0101 | 01000 | 02000000, 0600);
|
||||
if (fd >= 0) { write(fd, "xfixes-v1\n", 10); close(fd); }
|
||||
}
|
||||
return (void *)capture_image;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
在新工单中引用
屏蔽一个用户