vnc: first working RFB client, sends raw frames to SDL window
This commit is contained in:
commit
be9978c308
|
@ -0,0 +1,2 @@
|
|||
/vnc-client/build
|
||||
/vnc-client/cgvm_vnc
|
|
@ -0,0 +1,16 @@
|
|||
Setting up the extra display and starting wayvnc
|
||||
|
||||
```
|
||||
% swaymsg create_output
|
||||
% swaymsg output "HEADLESS-1" resolution 396x224
|
||||
% wayvnc -o HEADLESS-1
|
||||
```
|
||||
|
||||
Compiling and starting the VNC client
|
||||
|
||||
```
|
||||
% cd vnc-client
|
||||
% cmake -B build
|
||||
% make -C build
|
||||
% ./cgvm_vnc
|
||||
```
|
|
@ -0,0 +1,10 @@
|
|||
cmake_minimum_required(VERSION 3.15)
|
||||
project(CGVirtualMonitorVNCClient VERSION 1.0 LANGUAGES C)
|
||||
|
||||
find_package(LibVNCServer 0.9 REQUIRED)
|
||||
find_package(SDL2 2.0 REQUIRED)
|
||||
|
||||
add_executable(cgvm_vnc src/main.c)
|
||||
set_target_properties(cgvm_vnc PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
target_link_libraries(cgvm_vnc LibVNCServer::vncclient SDL2::SDL2)
|
|
@ -0,0 +1,96 @@
|
|||
#include <SDL2/SDL.h>
|
||||
#include <rfb/rfbclient.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* Application globals */
|
||||
struct app {
|
||||
rfbClient *client;
|
||||
SDL_Window *window;
|
||||
SDL_Surface *surface;
|
||||
};
|
||||
static struct app app = { 0 };
|
||||
|
||||
static void cleanup(void)
|
||||
{
|
||||
if(app.client)
|
||||
rfbClientCleanup(app.client);
|
||||
if(app.window)
|
||||
SDL_DestroyWindow(app.window);
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
static void fb_update(rfbClient *client)
|
||||
{
|
||||
/* SDL_LockSurface(app.surface);
|
||||
assert(app.surface->format->BytesPerPixel == 4);
|
||||
uint8_t *buffer = (void *)app.surface->pixels;
|
||||
for(int y = 0; y < app.surface->h; y++) {
|
||||
for(int x = 0; x < app.surface->w; x++) {
|
||||
int offset = y * app.surface->pitch + 4 * x;
|
||||
// R, G, B
|
||||
buffer[offset + 2] = 255;
|
||||
buffer[offset + 1] = 255;
|
||||
buffer[offset + 0] = 0;
|
||||
}
|
||||
}
|
||||
SDL_UnlockSurface(app.surface); */
|
||||
SDL_UpdateWindowSurface(app.window);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
atexit(cleanup);
|
||||
signal(SIGINT, exit);
|
||||
|
||||
app.window = SDL_CreateWindow("CG Virtual Monitor test VNC client",
|
||||
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 396, 224, 0);
|
||||
app.surface = SDL_GetWindowSurface(app.window);
|
||||
|
||||
app.client = rfbGetClient(8, 3, 4);
|
||||
app.client->FinishedFrameBufferUpdate = fb_update;
|
||||
app.client->width = 396;
|
||||
app.client->height = 224;
|
||||
app.client->frameBuffer = app.surface->pixels;
|
||||
|
||||
app.client->format.bitsPerPixel=32;
|
||||
app.client->format.redShift=app.surface->format->Rshift;
|
||||
app.client->format.greenShift=app.surface->format->Gshift;
|
||||
app.client->format.blueShift=app.surface->format->Bshift;
|
||||
app.client->format.redMax=app.surface->format->Rmask>>app.client->format.redShift;
|
||||
app.client->format.greenMax=app.surface->format->Gmask>>app.client->format.greenShift;
|
||||
app.client->format.blueMax=app.surface->format->Bmask>>app.client->format.blueShift;
|
||||
SetFormatAndEncodings(app.client);
|
||||
|
||||
int argc = 4;
|
||||
char *argv[] = { "cgvm_vnc", "-encodings", "raw", "127.0.0.1", NULL };
|
||||
if(!rfbInitClient(app.client, &argc, argv)) {
|
||||
fprintf(stderr, "rfbInitClient failed\n");
|
||||
app.client = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
SDL_Event e;
|
||||
while(SDL_PollEvent(&e)) {
|
||||
if(e.type == SDL_QUIT) {
|
||||
fprintf(stderr, "SDL_QUIT: Exiting...\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
int i = WaitForMessage(app.client, 100);
|
||||
if(i < 0) {
|
||||
fprintf(stderr, "WaitForMessage() select: %d\n", i);
|
||||
continue;
|
||||
}
|
||||
else if(i > 0 && !HandleRFBServerMessage(app.client)) {
|
||||
fprintf(stderr, "HandleRFBServerMessage() failed\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue