vnc: structure improvements, don't use SDL unless requested
This commit is contained in:
parent
b6c782666c
commit
74a7f05e9d
|
@ -7,6 +7,10 @@
|
|||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/* Size of the calculator display */
|
||||
#define CALC_WIDTH 396
|
||||
#define CALC_HEIGHT 224
|
||||
|
||||
/* Application globals */
|
||||
struct app {
|
||||
/* RFB/VNC client to get framebuffers from VNC server */
|
||||
|
@ -56,26 +60,29 @@ static void cleanup(void)
|
|||
new 16-bit framebuffer to the calculator. */
|
||||
static void fb_update(rfbClient *client)
|
||||
{
|
||||
uint32_t *fb = (void *)client->frameBuffer;
|
||||
|
||||
if(app.display_sdl) {
|
||||
/* Very crude assumption about the SDL surface format and pitch */
|
||||
memcpy(app.surface->pixels, fb, CALC_WIDTH * CALC_HEIGHT * 4);
|
||||
SDL_UpdateWindowSurface(app.window);
|
||||
}
|
||||
if(app.display_calc && app.calc && app.fb16_be) {
|
||||
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;
|
||||
int R = buffer[offset + 2];
|
||||
int G = buffer[offset + 1];
|
||||
int B = buffer[offset + 0];
|
||||
if(app.display_calc && app.calc && app.fb16_be) {
|
||||
for(int y = 0; y < CALC_HEIGHT; y++)
|
||||
for(int x = 0; x < CALC_WIDTH; x++) {
|
||||
uint32_t color = fb[CALC_WIDTH * y + x];
|
||||
int R = (color >> 16) & 0xff;
|
||||
int G = (color >> 8) & 0xff;
|
||||
int B = (color & 0xff);
|
||||
|
||||
/* Conversion to RGB565 */
|
||||
int c = ((R & 0xf8) << 8) | ((G & 0xfc) << 3) | ((B & 0xf8) >> 3);
|
||||
app.fb16_be[396*y + x] = (c >> 8) | (c << 8);
|
||||
app.fb16_be[CALC_WIDTH * y + x] = (c >> 8) | (c << 8);
|
||||
}
|
||||
|
||||
fxlink_device_start_bulk_OUT(app.calc,
|
||||
"cgvm", "fb", app.fb16_be, 396*224*2, false);
|
||||
"cgvm", "fb", app.fb16_be, CALC_WIDTH * CALC_HEIGHT * 2, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,6 +182,40 @@ static void usage(int rc)
|
|||
exit(rc);
|
||||
}
|
||||
|
||||
static bool init_rfb_client(rfbClient **client, char *server,
|
||||
uint32_t *fb)
|
||||
{
|
||||
int argc = 4;
|
||||
char *argv[] = { "cgvm_vnc", "-encodings", "raw", server, NULL };
|
||||
|
||||
*client = rfbGetClient(8, 3, 4);
|
||||
if(!*client) {
|
||||
fprintf(stderr, "rfbGetClient failed\n");
|
||||
return false;
|
||||
}
|
||||
(*client)->FinishedFrameBufferUpdate = fb_update;
|
||||
(*client)->width = CALC_WIDTH;
|
||||
(*client)->height = CALC_HEIGHT;
|
||||
(*client)->frameBuffer = (void *)fb;
|
||||
|
||||
/* Standard 32-bit xRGB */
|
||||
(*client)->format.bitsPerPixel = 32;
|
||||
(*client)->format.redShift = 16;
|
||||
(*client)->format.greenShift = 8;
|
||||
(*client)->format.blueShift = 0;
|
||||
(*client)->format.redMax = 0xff;
|
||||
(*client)->format.greenMax = 0xff;
|
||||
(*client)->format.blueMax = 0xff;
|
||||
SetFormatAndEncodings(*client);
|
||||
|
||||
if(!rfbInitClient(*client, &argc, argv)) {
|
||||
fprintf(stderr, "rfbInitClient failed\n");
|
||||
*client = NULL;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
for(int i = 1; i < argc; i++) {
|
||||
|
@ -195,39 +236,31 @@ int main(int argc, char **argv)
|
|||
usage(1);
|
||||
|
||||
atexit(cleanup);
|
||||
/* TODO: Sometimes when calc disconnects process loops and is unkillable */
|
||||
/* TODO: Sometimes when the calculator disconnects the wait on the RFB
|
||||
server loops and can't be killed by SIGINT or SIGTERM? */
|
||||
signal(SIGINT, exit);
|
||||
|
||||
/* Create the SDL window regarless of whether display_sdl is set, since we
|
||||
use its surface as RFB framebuffer */
|
||||
/* TODO: Use an external framebuffer, don't use SDL unless enabled */
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
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);
|
||||
assert(app.surface->format->BytesPerPixel == 4);
|
||||
//---
|
||||
// Initialise the RFB client
|
||||
//---
|
||||
|
||||
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;
|
||||
uint32_t *fb = malloc(CALC_WIDTH * CALC_HEIGHT * 4);
|
||||
assert(fb && "out of memory");
|
||||
|
||||
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[] = { argv[0], "-encodings", "raw", "127.0.0.1", NULL };
|
||||
if(!rfbInitClient(app.client, &_argc, _argv)) {
|
||||
fprintf(stderr, "rfbInitClient failed\n");
|
||||
app.client = NULL;
|
||||
if(!init_rfb_client(&app.client, "127.0.0.1", fb))
|
||||
return 1;
|
||||
|
||||
/* Create the SDL window if SDL display is requested */
|
||||
if(app.display_sdl) {
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
app.window = SDL_CreateWindow("CG Virtual Monitor test VNC client",
|
||||
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||
CALC_WIDTH, CALC_HEIGHT, 0);
|
||||
app.surface = SDL_GetWindowSurface(app.window);
|
||||
|
||||
/* Surely this is gonna be the default everywhere, like surely */
|
||||
assert(app.surface->format->BytesPerPixel == 4);
|
||||
assert(app.surface->format->format == SDL_PIXELFORMAT_RGB888);
|
||||
}
|
||||
|
||||
if(app.display_calc) {
|
||||
|
@ -241,15 +274,17 @@ int main(int argc, char **argv)
|
|||
|
||||
/* Track the list of connected calculators. */
|
||||
fxlink_device_list_track(&app.devices, app.libusb_ctx);
|
||||
app.fb16_be = malloc(396 * 224 * 2);
|
||||
app.fb16_be = malloc(CALC_WIDTH * CALC_HEIGHT * 2);
|
||||
}
|
||||
|
||||
while(1) {
|
||||
SDL_Event e;
|
||||
while(SDL_PollEvent(&e)) {
|
||||
if(e.type == SDL_QUIT) {
|
||||
fprintf(stderr, "SDL_QUIT: Exiting...\n");
|
||||
exit(0);
|
||||
if(app.display_sdl) {
|
||||
SDL_Event e;
|
||||
while(SDL_PollEvent(&e)) {
|
||||
if(e.type == SDL_QUIT) {
|
||||
fprintf(stderr, "SDL_QUIT: Exiting...\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue