Add VNC code

qemu-extended-key-event
Andri Yngvason 2020-07-10 00:14:29 +00:00
parent dc97cc73c2
commit 7ebeeefb10
2 changed files with 100 additions and 36 deletions

View File

@ -29,6 +29,7 @@ librt = cc.find_library('rt', required: false)
pixman = dependency('pixman-1') pixman = dependency('pixman-1')
wayland_client = dependency('wayland-client') wayland_client = dependency('wayland-client')
libvncclient = dependency('libvncclient')
aml_project = subproject('aml', required: false) aml_project = subproject('aml', required: false)
if aml_project.found() if aml_project.found()
@ -52,6 +53,7 @@ dependencies = [
pixman, pixman,
aml, aml,
wayland_client, wayland_client,
libvncclient,
client_protos, client_protos,
] ]

View File

@ -10,6 +10,7 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <aml.h> #include <aml.h>
#include <wayland-client.h> #include <wayland-client.h>
#include <rfb/rfbclient.h>
#include "xdg-shell.h" #include "xdg-shell.h"
#include "shm.h" #include "shm.h"
@ -27,9 +28,8 @@ struct window {
struct xdg_surface* xdg_surface; struct xdg_surface* xdg_surface;
struct xdg_toplevel* xdg_toplevel; struct xdg_toplevel* xdg_toplevel;
int width, height;
struct buffer* buffer; struct buffer* buffer;
bool is_attached;
}; };
static struct wl_display* wl_display; static struct wl_display* wl_display;
@ -43,6 +43,8 @@ static bool have_format = false;
static bool do_run = true; static bool do_run = true;
struct window* window = NULL;
static void registry_add(void* data, struct wl_registry* registry, uint32_t id, static void registry_add(void* data, struct wl_registry* registry, uint32_t id,
const char* interface, uint32_t version) const char* interface, uint32_t version)
{ {
@ -215,28 +217,9 @@ static void window_damage(struct window* w, int x, int y, int width, int height)
wl_surface_damage(w->wl_surface, x, y, width, height); wl_surface_damage(w->wl_surface, x, y, width, height);
} }
static void window_clear(struct window* w)
{
window_attach(w, 0, 0);
memset(w->buffer->pixels, 0x7f, w->buffer->size);
window_damage(w, 0, 0, w->width, w->height);
window_commit(w);
}
static void window_configure(struct window* w) static void window_configure(struct window* w)
{ {
if (w->buffer && (w->width != w->buffer->width || // What to do here?
w->height != w->buffer->height)) {
buffer_destroy(w->buffer);
w->buffer = NULL;
}
if (!w->buffer)
w->buffer = buffer_create(w->width, w->height, w->width * 4,
wl_shm_format);
assert(w->buffer);
window_clear(w);
} }
static void xdg_surface_configure(void* data, struct xdg_surface* surface, static void xdg_surface_configure(void* data, struct xdg_surface* surface,
@ -254,9 +237,7 @@ static const struct xdg_surface_listener xdg_surface_listener = {
static void xdg_toplevel_configure(void* data, struct xdg_toplevel* toplevel, static void xdg_toplevel_configure(void* data, struct xdg_toplevel* toplevel,
int32_t width, int32_t height, struct wl_array* state) int32_t width, int32_t height, struct wl_array* state)
{ {
// struct window* w = data; // What to do here?
// w->width = width;
// w->height = height;
} }
static void xdg_toplevel_close(void* data, struct xdg_toplevel* toplevel) static void xdg_toplevel_close(void* data, struct xdg_toplevel* toplevel)
@ -269,15 +250,12 @@ static const struct xdg_toplevel_listener xdg_toplevel_listener = {
.close = xdg_toplevel_close, .close = xdg_toplevel_close,
}; };
static struct window* window_create(int width, int height, const char* title) static struct window* window_create(const char* title)
{ {
struct window* w = calloc(1, sizeof(*w)); struct window* w = calloc(1, sizeof(*w));
if (!w) if (!w)
return NULL; return NULL;
w->width = width;
w->height = height;
w->wl_surface = wl_compositor_create_surface(wl_compositor); w->wl_surface = wl_compositor_create_surface(wl_compositor);
if (!w->wl_surface) if (!w->wl_surface)
goto wl_surface_failure; goto wl_surface_failure;
@ -297,8 +275,6 @@ static struct window* window_create(int width, int height, const char* title)
xdg_toplevel_set_title(w->xdg_toplevel, title); xdg_toplevel_set_title(w->xdg_toplevel, title);
wl_surface_commit(w->wl_surface); wl_surface_commit(w->wl_surface);
window_damage(w, 0, 0, width, height);
return w; return w;
xdg_toplevel_failure: xdg_toplevel_failure:
@ -321,6 +297,89 @@ static void window_destroy(struct window* w)
free(w); free(w);
} }
rfbBool rfb_client_alloc_fb(rfbClient* cl)
{
int stride = cl->width * 4; // TODO
assert(!window); // TODO
window = window_create(cl->desktopName);
if (!window)
return FALSE;
window->buffer = buffer_create(cl->width, cl->height, stride,
wl_shm_format);
cl->frameBuffer = window->buffer->pixels;
return TRUE;
}
void rfb_client_update_box(rfbClient* cl, int x, int y, int width, int height)
{
if (!window->is_attached)
window_attach(window, 0, 0);
window_damage(window, x, y, width, height);
}
void rfb_client_finish_update(rfbClient* cl)
{
window_commit(window);
}
void on_rfb_client_server_event(void* obj)
{
rfbClient* cl = aml_get_userdata(obj);
if (!HandleRFBServerMessage(cl))
do_run = false;
}
static rfbClient* rfb_client_create(int* argc, char* argv[])
{
int bits_per_sample = 8;
int samples_per_pixel = 3;
int bytes_per_pixel = 4;
rfbClient* cl = rfbGetClient(bits_per_sample, samples_per_pixel,
bytes_per_pixel);
if (!cl)
return NULL;
// TODO: Set correct pixel format here
cl->MallocFrameBuffer = rfb_client_alloc_fb;
cl->GotFrameBufferUpdate = rfb_client_update_box;
cl->FinishedFrameBufferUpdate = rfb_client_finish_update;
if (!rfbInitClient(cl, argc, argv))
goto failure;
int fd = cl->sock;
struct aml_handler* handler;
handler = aml_handler_new(fd, on_rfb_client_server_event, cl, NULL);
if (!handler)
goto failure;
int rc = aml_start(aml_get_default(), handler);
aml_unref(handler);
if (rc < 0)
goto failure;
return cl;
failure:
rfbClientCleanup(cl);
return NULL;
}
static void rfb_client_destroy(rfbClient* cl)
{
rfbClientCleanup(cl);
}
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
int rc = -1; int rc = -1;
@ -356,9 +415,10 @@ int main(int argc, char* argv[])
xdg_wm_base_add_listener(xdg_wm_base, &xdg_wm_base_listener, NULL); xdg_wm_base_add_listener(xdg_wm_base, &xdg_wm_base_listener, NULL);
wl_display_roundtrip(wl_display); wl_display_roundtrip(wl_display);
struct window* window = window_create(512, 512, "wlvncc"); rfbClient* vnc = rfb_client_create(&argc, argv);
if (!window) if (!vnc)
goto window_failure; goto vnc_failure;
wl_display_dispatch(wl_display); wl_display_dispatch(wl_display);
@ -369,8 +429,10 @@ int main(int argc, char* argv[])
} }
rc = 0; rc = 0;
if (window)
window_destroy(window); window_destroy(window);
window_failure: rfb_client_destroy(vnc);
vnc_failure:
wl_compositor_destroy(wl_compositor); wl_compositor_destroy(wl_compositor);
wl_shm_destroy(wl_shm); wl_shm_destroy(wl_shm);
xdg_wm_base_destroy(xdg_wm_base); xdg_wm_base_destroy(xdg_wm_base);