Add VNC code
parent
dc97cc73c2
commit
7ebeeefb10
|
@ -29,6 +29,7 @@ librt = cc.find_library('rt', required: false)
|
|||
|
||||
pixman = dependency('pixman-1')
|
||||
wayland_client = dependency('wayland-client')
|
||||
libvncclient = dependency('libvncclient')
|
||||
|
||||
aml_project = subproject('aml', required: false)
|
||||
if aml_project.found()
|
||||
|
@ -52,6 +53,7 @@ dependencies = [
|
|||
pixman,
|
||||
aml,
|
||||
wayland_client,
|
||||
libvncclient,
|
||||
client_protos,
|
||||
]
|
||||
|
||||
|
|
132
src/main.c
132
src/main.c
|
@ -10,6 +10,7 @@
|
|||
#include <sys/mman.h>
|
||||
#include <aml.h>
|
||||
#include <wayland-client.h>
|
||||
#include <rfb/rfbclient.h>
|
||||
|
||||
#include "xdg-shell.h"
|
||||
#include "shm.h"
|
||||
|
@ -27,9 +28,8 @@ struct window {
|
|||
struct xdg_surface* xdg_surface;
|
||||
struct xdg_toplevel* xdg_toplevel;
|
||||
|
||||
int width, height;
|
||||
|
||||
struct buffer* buffer;
|
||||
bool is_attached;
|
||||
};
|
||||
|
||||
static struct wl_display* wl_display;
|
||||
|
@ -43,6 +43,8 @@ static bool have_format = false;
|
|||
|
||||
static bool do_run = true;
|
||||
|
||||
struct window* window = NULL;
|
||||
|
||||
static void registry_add(void* data, struct wl_registry* registry, uint32_t id,
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (w->buffer && (w->width != w->buffer->width ||
|
||||
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);
|
||||
// What to do here?
|
||||
}
|
||||
|
||||
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,
|
||||
int32_t width, int32_t height, struct wl_array* state)
|
||||
{
|
||||
// struct window* w = data;
|
||||
// w->width = width;
|
||||
// w->height = height;
|
||||
// What to do here?
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
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));
|
||||
if (!w)
|
||||
return NULL;
|
||||
|
||||
w->width = width;
|
||||
w->height = height;
|
||||
|
||||
w->wl_surface = wl_compositor_create_surface(wl_compositor);
|
||||
if (!w->wl_surface)
|
||||
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);
|
||||
wl_surface_commit(w->wl_surface);
|
||||
|
||||
window_damage(w, 0, 0, width, height);
|
||||
|
||||
return w;
|
||||
|
||||
xdg_toplevel_failure:
|
||||
|
@ -321,6 +297,89 @@ static void window_destroy(struct window* 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 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);
|
||||
wl_display_roundtrip(wl_display);
|
||||
|
||||
struct window* window = window_create(512, 512, "wlvncc");
|
||||
if (!window)
|
||||
goto window_failure;
|
||||
rfbClient* vnc = rfb_client_create(&argc, argv);
|
||||
if (!vnc)
|
||||
goto vnc_failure;
|
||||
|
||||
|
||||
wl_display_dispatch(wl_display);
|
||||
|
||||
|
@ -369,8 +429,10 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
rc = 0;
|
||||
if (window)
|
||||
window_destroy(window);
|
||||
window_failure:
|
||||
rfb_client_destroy(vnc);
|
||||
vnc_failure:
|
||||
wl_compositor_destroy(wl_compositor);
|
||||
wl_shm_destroy(wl_shm);
|
||||
xdg_wm_base_destroy(xdg_wm_base);
|
||||
|
|
Loading…
Reference in New Issue