This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch master in repository x2gokdrive. commit 7707e4d35bd9a3c6bb904a1abf109dc528a7ea5e Author: Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> Date: Thu Feb 11 19:30:52 2021 -0600 add some support for HTML5 client (like converting pointer cursors to PNG format). --- debian/changelog | 1 + x2gokdriveremote.c | 50 ++++++++++++++++++++++++++++++++++++++++---------- x2gokdriveremote.h | 8 +++++--- x2gokdriveselection.c | 4 ++-- 4 files changed, 48 insertions(+), 15 deletions(-) diff --git a/debian/changelog b/debian/changelog index a38d2b9..c65b49d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -16,6 +16,7 @@ x2gokdrive (0.0.0.1-0x2go1) UNRELEASED; urgency=medium - reinit client version on new connection and awaka sending thread when client version recieved. - support sending and recieving selections on demand. Support reading and writing INCR properties. - move declaration of RemoteHostVars from x2gokdriveremote.h to x2gokdriveremote.c. + - add some support for HTML5 client (like converting pointer cursors to PNG format). [ Mihai Moldovan ] * Initial release: diff --git a/x2gokdriveremote.c b/x2gokdriveremote.c index 35ac570..a41cfb4 100644 --- a/x2gokdriveremote.c +++ b/x2gokdriveremote.c @@ -267,9 +267,18 @@ void remote_sendCursor(CursorPtr cursor) { if(cursor->bits->argb) { - cframe->size=cursor->bits->width*cursor->bits->height*4; - cframe->data=malloc(cframe->size); - memcpy(cframe->data, cursor->bits->argb, cframe->size); + if(remoteVars.client_os == WEB) + { + //for web client we need to convert cursor data to PNG format + cframe->data=(char*)png_compress( cursor->bits->width, cursor->bits->height, + (unsigned char *)cursor->bits->argb, &cframe->size, TRUE); + } + else + { + cframe->size=cursor->bits->width*cursor->bits->height*4; + cframe->data=malloc(cframe->size); + memcpy(cframe->data, cursor->bits->argb, cframe->size); + } } else { @@ -2412,6 +2421,11 @@ clientReadNotify(int fd, int ready, void *data) client_sel_request_notify(sel); break; } + case KEEPALIVE: + { + //receive keepalive event, don't need to do anything + break; + } default: { EPHYR_DBG("UNSUPPORTED EVENT: %d",event_type); @@ -2436,7 +2450,7 @@ clientReadNotify(int fd, int ready, void *data) void set_client_version(uint16_t ver, uint16_t os) { remoteVars.client_version=ver; - if(os > OS_DARWIN) + if(os > WEB) { EPHYR_DBG("Unsupported OS, assuming OS_LINUX"); } @@ -2773,7 +2787,7 @@ static void PngWriteCallback(png_structp png_ptr, png_bytep data, png_size_t le } unsigned char* png_compress( uint32_t image_width, uint32_t image_height, - unsigned char* RGBA_buffer, uint32_t* png_size) + unsigned char* RGBA_buffer, uint32_t* png_size, BOOL compress_cursor) { struct { @@ -2781,17 +2795,33 @@ unsigned char* png_compress( uint32_t image_width, uint32_t image_height, unsigned char *out; } outdata; unsigned char** rows = NULL; + int color_type; + int bpp; + png_structp p; + png_infop info_ptr; + + if(compress_cursor) + { + color_type = PNG_COLOR_TYPE_RGB_ALPHA; + bpp = 4; + } + else + { + color_type = PNG_COLOR_TYPE_RGB; + bpp = CACHEBPP; + } - png_structp p = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + p = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - png_infop info_ptr = png_create_info_struct(p); + info_ptr = png_create_info_struct(p); setjmp(png_jmpbuf(p)); png_set_IHDR(p, info_ptr,image_width, image_height, 8, - PNG_COLOR_TYPE_RGB, + color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + *png_size=0; rows = calloc(sizeof(unsigned char*), image_height); @@ -2800,7 +2830,7 @@ unsigned char* png_compress( uint32_t image_width, uint32_t image_height, outdata.out=0; for (uint32_t y = 0; y < image_height; ++y) - rows[y] = (unsigned char*)RGBA_buffer + y * image_width * CACHEBPP; + rows[y] = (unsigned char*)RGBA_buffer + y * image_width * bpp; png_set_rows(p, info_ptr, &rows[0]); @@ -2880,7 +2910,7 @@ unsigned char* image_compress(uint32_t image_width, uint32_t image_height, if(remoteVars.compression==JPEG) return jpeg_compress(remoteVars.jpegQuality, image_width, image_height, RGBA_buffer, compressed_size, bpp, fname); else - return png_compress(image_width, image_height, RGBA_buffer, compressed_size); + return png_compress(image_width, image_height, RGBA_buffer, compressed_size, FALSE); } static diff --git a/x2gokdriveremote.h b/x2gokdriveremote.h index e87c3ab..0b03917 100644 --- a/x2gokdriveremote.h +++ b/x2gokdriveremote.h @@ -96,7 +96,8 @@ //it used to tell server which features are supported by server //Changes 0 - 1: sending and recieving client and OS version //Changes 1 - 2: supporting extended selection and sending selection on demand -#define FEATURE_VERSION 2 +//Changes 2 - 3: supporting web client, sending cursors in PNG format and know about KEEPALIVE event +#define FEATURE_VERSION 3 #define EPHYR_WANT_DEBUG 1 @@ -137,7 +138,7 @@ enum Compressions{JPEG,PNG}; enum SelectionType{PRIMARY,CLIPBOARD}; enum SelectionMime{STRING,UTF_STRING,PIXMAP}; enum ClipboardMode{CLIP_NONE,CLIP_CLIENT,CLIP_SERVER,CLIP_BOTH}; -enum OS_VERSION{OS_LINUX, OS_WINDOWS, OS_DARWIN}; +enum OS_VERSION{OS_LINUX, OS_WINDOWS, OS_DARWIN, WEB}; #define DEFAULT_COMPRESSION JPEG @@ -162,6 +163,7 @@ enum OS_VERSION{OS_LINUX, OS_WINDOWS, OS_DARWIN}; #define SELECTIONEVENT 9 #define CLIENTVERSION 10 #define DEMANDSELECTION 11 +#define KEEPALIVE 12 #define EVLENGTH 41 @@ -481,7 +483,7 @@ unsigned char* jpeg_compress(int quality, uint32_t image_width, uint32_t image_h unsigned char* RGBA_buffer, uint32_t* jpeg_size, int bpp, char* fname); unsigned char* png_compress(uint32_t image_width, uint32_t image_height, - unsigned char* RGBA_buffer, uint32_t* png_size); + unsigned char* RGBA_buffer, uint32_t* png_size, BOOL compress_cursor); void clientReadNotify(int fd, int ready, void *data); diff --git a/x2gokdriveselection.c b/x2gokdriveselection.c index e3e6857..85447a3 100644 --- a/x2gokdriveselection.c +++ b/x2gokdriveselection.c @@ -659,7 +659,7 @@ void read_selection_property(xcb_atom_t selection, xcb_atom_t property) free(chunk->data); chunk->data=compressed_data; chunk->compressed_size=compressed_size; -// EPHYR_DBG("compressed chunk from %d to %d", chunk->size, chunk->compressed_size); + EPHYR_DBG("compressed chunk from %d to %d", chunk->size, chunk->compressed_size); } } } @@ -722,7 +722,7 @@ void read_selection_property(xcb_atom_t selection, xcb_atom_t property) remoteVars->selstruct.lastOutputChunk->next=chunk; remoteVars->selstruct.lastOutputChunk=chunk; } -// EPHYR_DBG(" ADD CHUNK %p %p %p", remoteVars->selstruct.firstOutputChunk, remoteVars->selstruct.lastOutputChunk, chunk); + EPHYR_DBG(" ADD CHUNK %p %p %p", remoteVars->selstruct.firstOutputChunk, remoteVars->selstruct.lastOutputChunk, chunk); pthread_cond_signal(&remoteVars->have_sendqueue_cond); -- Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2gokdrive.git