Add VNC code
parent
dc97cc73c2
commit
7ebeeefb10
|
@ -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,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
132
src/main.c
132
src/main.c
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue