This commit is contained in:
JerryXiao 2023-04-25 14:37:50 +08:00
parent d9eaf737bd
commit 642b1f9903
Signed by: Jerry
GPG key ID: 22618F758B5BE2E5

View file

@ -8,7 +8,6 @@
#include <libdrm/i915_drm.h> #include <libdrm/i915_drm.h>
#include <libdrm/amdgpu_drm.h> #include <libdrm/amdgpu_drm.h>
#include <xf86drmMode.h> #include <xf86drmMode.h>
//#include <cairo.h>
#include <linux/uinput.h> #include <linux/uinput.h>
#include <xkbcommon/xkbcommon.h> #include <xkbcommon/xkbcommon.h>
#include <math.h> #include <math.h>
@ -18,7 +17,7 @@
/* 10 frames per second (if we can) */ /* 10 frames per second (if we can) */
#define PICTURE_TIMEOUT (1.0/10.0) #define PICTURE_TIMEOUT (1.0/10.0)
#define UINPUT_ABS_MAX INT16_MAX #define UINPUT_ABS_MAX INT16_MAX
#define UINPUT_MAX_KEY 256
struct Vec2d { struct Vec2d {
int x; int x;
@ -62,9 +61,8 @@ struct vnc_xkb {
}; };
struct vnc_xkb xkb; struct vnc_xkb xkb;
#define MAX_KEYS 256
int uinput_fd = 0; int uinput_fd = 0;
char keystate[MAX_KEYS]; char keystate[UINPUT_MAX_KEY];
static void xkb_init() { static void xkb_init() {
xkb.ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS); xkb.ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
if (xkb.ctx == NULL) { if (xkb.ctx == NULL) {
@ -80,10 +78,10 @@ static void xkb_init() {
}; };
xkb.map = xkb_keymap_new_from_names(xkb.ctx, &names, 0); xkb.map = xkb_keymap_new_from_names(xkb.ctx, &names, 0);
if (xkb.map == NULL) { if (xkb.map == NULL) {
fprintf(stderr, "Failed to create XKB context\n"); fprintf(stderr, "Failed to create XKB map\n");
exit(1); exit(1);
} }
printf("xkb: keymap = %s\n", xkb_keymap_get_as_string(xkb.map, XKB_KEYMAP_USE_ORIGINAL_FORMAT)); //printf("xkb: keymap = %s\n", xkb_keymap_get_as_string(xkb.map, XKB_KEYMAP_USE_ORIGINAL_FORMAT));
} }
static void uinput_init() { static void uinput_init() {
@ -95,7 +93,7 @@ static void uinput_init() {
} }
ioctl(uinput_fd, UI_SET_EVBIT, EV_KEY); ioctl(uinput_fd, UI_SET_EVBIT, EV_KEY);
ioctl(uinput_fd, UI_SET_EVBIT, EV_SYN); ioctl(uinput_fd, UI_SET_EVBIT, EV_SYN);
for (int i = 0; i < MAX_KEYS; i++) { for (int i = 0; i < UINPUT_MAX_KEY; i++) {
ioctl(uinput_fd, UI_SET_KEYBIT, i); ioctl(uinput_fd, UI_SET_KEYBIT, i);
} }
@ -128,7 +126,7 @@ static void uinput_init() {
ioctl(uinput_fd, UI_DEV_SETUP, &usetup); ioctl(uinput_fd, UI_DEV_SETUP, &usetup);
ioctl(uinput_fd, UI_DEV_CREATE); ioctl(uinput_fd, UI_DEV_CREATE);
memset(keystate, 0, MAX_KEYS); memset(keystate, 0, UINPUT_MAX_KEY);
} }
struct key_iter_search { struct key_iter_search {
@ -172,15 +170,15 @@ static void rfb_key_hook(rfbBool down, rfbKeySym keysym, rfbClientPtr cl) {
return; return;
} }
printf("key %s, keysym %04x, keycode %u\n", down ? "down" : "up", keysym, search.keycode); printf("key %s, keysym %04x, keycode %u\n", down ? "down" : "up", keysym, search.keycode);
if (search.keycode >= MAX_KEYS) { if (search.keycode >= UINPUT_MAX_KEY) {
fprintf(stderr, "Keycode %d >= %d\n", search.keycode, MAX_KEYS); fprintf(stderr, "Keycode %d >= %d\n", search.keycode, UINPUT_MAX_KEY);
return; return;
} }
if (down != keystate[search.keycode]) { if (down != keystate[search.keycode]) {
struct input_event ies[] = { struct input_event ies[] = {
{ {
.type = EV_KEY, .type = EV_KEY,
.code = search.keycode, .code = search.keycode - 8, // magic
.value = down, .value = down,
.time.tv_sec = 0, .time.tv_sec = 0,
.time.tv_usec = 0, .time.tv_usec = 0,
@ -347,11 +345,11 @@ int main(int argc, const char **argv)
goto cleanup; goto cleanup;
} }
printf("Template framebuffer is %u: %ux%u %ubpp %ub depth %u pitch\n", fb->fb_id, fb->width, fb->height, fb->bpp, fb->depth, fb->pitch); printf("Template framebuffer is %u: %ux%u %ubpp %ub depth %u pitch\n", fb->fb_id, fb->width, fb->height, fb->bpp, fb->depth, fb->pitch);
//printf("Template framebuffer is %u: %ux%u fourcc:%u mod:%u flags:%u\n", fb->fb_id, fb->width, fb->height, fb->pixel_format, fb->modifier, fb->flags);
//printf("handles %u %u %u %u\n", fb->handles[0], fb->handles[1], fb->handles[2], fb->handles[3]); if (fb->bpp != 32 || fb->depth != 24) {
//printf("offsets %u %u %u %u\n", fb->offsets[0], fb->offsets[1], fb->offsets[2], fb->offsets[3]); fprintf(stderr, "Unsupported pixfmt\n");
//printf("pitches %u %u %u %u\n", fb->pitches[0], fb->pitches[1], fb->pitches[2], fb->pitches[3]); goto cleanup;
//printf("format %s, modifier %s:%s\n", drmGetFormatName(fb->pixel_format), drmGetFormatModifierVendor(fb->modifier), drmGetFormatModifierName(fb->modifier)); }
if (!fb->handle) { if (!fb->handle) {
fprintf(stderr, "No handle set on framebuffer: maybe you need some additional capabilities?\n"); fprintf(stderr, "No handle set on framebuffer: maybe you need some additional capabilities?\n");
@ -374,6 +372,7 @@ int main(int argc, const char **argv)
off_t mmap_offset = 0; off_t mmap_offset = 0;
size_t mmap_size = 0; size_t mmap_size = 0;
printf("drm driver is %s\n", drm_ver->name); printf("drm driver is %s\n", drm_ver->name);
char *mapped = NULL;
if (strcmp(drm_ver->name, "i915") == 0) { if (strcmp(drm_ver->name, "i915") == 0) {
struct drm_i915_gem_mmap_gtt mmap_arg; struct drm_i915_gem_mmap_gtt mmap_arg;
mmap_arg.handle = open_arg.handle; mmap_arg.handle = open_arg.handle;
@ -395,30 +394,35 @@ int main(int argc, const char **argv)
mmap_size = open_arg.size; mmap_size = open_arg.size;
mmap_offset = mmap_arg.out.addr_ptr; mmap_offset = mmap_arg.out.addr_ptr;
} }
else if (strcmp(drm_ver->name, "nothing") == 0) {
struct drm_mode_map_dumb mreq;
memset(&mreq, 0, sizeof(mreq));
mreq.handle = open_arg.handle;
if (ioctl_err = drmIoctl(drmfd, DRM_IOCTL_MODE_MAP_DUMB, &mreq)) {
fprintf(stderr, "DRM ioctl error %d on line %d\n", ioctl_err, __LINE__);
goto cleanup;
}
mmap_size = open_arg.size;
mmap_offset = mreq.offset;
}
else { else {
fprintf(stderr, "Unimplemented drm driver\n"); fprintf(stderr, "Unimplemented drm driver\n");
goto cleanup; goto cleanup;
} }
if (!mapped) {
printf("mapping with size = %d, offset = %d, drmfd = %d\n", mmap_size, mmap_offset, drmfd); printf("mapping with size = %d, offset = %d, drmfd = %d\n", mmap_size, mmap_offset, drmfd);
char *mapped = mmap(NULL, mmap_size, PROT_READ, MAP_SHARED, drmfd, mmap_offset); mapped = mmap(NULL, mmap_size, PROT_READ, MAP_SHARED, drmfd, mmap_offset);
if (mapped == MAP_FAILED) { if (mapped == MAP_FAILED) {
perror("mmap"); perror("mmap");
goto cleanup; goto cleanup;
} }
}
size_t buflen = fb->width * fb->height * 32 / 8; size_t buflen = fb->width * fb->height * 32 / 8;
char *buf = malloc(buflen); char *buf = malloc(buflen);
memset(buf, 0, buflen); memset(buf, 0, buflen);
char *buf2 = malloc(buflen); char *buf2 = malloc(buflen);
memset(buf2, 0, buflen); memset(buf2, 0, buflen);
//memcpy(buf, mapped, buflen);
//cairo_surface_t *surface = cairo_image_surface_create_for_data(buf, CAIRO_FORMAT_RGB24, fb->width, fb->height, fb->pitch);
//cairo_surface_write_to_png(surface, "/tmp/test-1.png");
//cairo_surface_destroy(surface);
//unlink("/tmp/1.raw");
//write(open("/tmp/1.raw", O_WRONLY | O_CREAT, 00644), buf, buflen);
resolution.x = fb->width; resolution.x = fb->width;
resolution.y = fb->height; resolution.y = fb->height;
@ -435,7 +439,6 @@ int main(int argc, const char **argv)
server->kbdAddEvent = rfb_key_hook; server->kbdAddEvent = rfb_key_hook;
server->ptrAddEvent = rfb_ptr_hook; server->ptrAddEvent = rfb_ptr_hook;
rfbInitServer(server); rfbInitServer(server);
//rfbRunEventLoop(server,40000,FALSE);
long usec; long usec;
while (rfbIsActive(server)) { while (rfbIsActive(server)) {
if (server->clientHead && TimeToTakePicture()) { if (server->clientHead && TimeToTakePicture()) {