diff options
-rw-r--r-- | vnc-client.c | 3 | ||||
-rw-r--r-- | vnc.c | 214 |
2 files changed, 118 insertions, 99 deletions
diff --git a/vnc-client.c b/vnc-client.c index 2883a0e..331fc86 100644 --- a/vnc-client.c +++ b/vnc-client.c @@ -26,7 +26,8 @@ static void usage(FILE *fp) " -d Enable debug output.\n" " -u Send us kbd layout keysyms.\n" " -p Show mouse pointer.\n" - " -g Enable OpenGL.\n" + " -g Enable OpenGL for fullscreen mode.\n" + " -G Enable OpenGL unconditionally.\n" " -o View only.\n" "\n" "-- \n" @@ -98,6 +98,7 @@ static int linux_uskbd_size = sizeof(linux_uskbd)/sizeof(linux_uskbd[0]); static GdkFilterReturn event_filter(GdkXEvent *gdkxevent, GdkEvent *gtkevent, gpointer data); +static void vnc_window_conf(struct vnc_window *vnc); /* ------------------------------------------------------------------ */ /* opengl bits */ @@ -372,15 +373,124 @@ static void dpy_flush(struct vnc_window *vnc, const char *caller) gl_flush(vnc); } +static int dpy_gl_check(struct vnc_window *vnc) +{ + int using_gl = 0; + + if (vnc->have_gl && vnc->vncdpy.w < vnc->tex_max && vnc->vncdpy.h < vnc->tex_max) { + if (vnc->gl_allways) + using_gl = 1; + if (vnc->gl_fullscreen && vnc->fullscreen) + using_gl = 1; + } + return using_gl; +} + +static void dpy_setup(struct vnc_window *vnc, int width, int height, int using_gl) +{ + /* cleanup */ + if (vnc->ximage) { + x11_destroy_ximage(vnc->dpy, vnc->ximage, vnc->shm); + vnc->ximage = NULL; + } + if (vnc->tex) { + /* FIXME: release texture */ + vnc->tex = 0; + vnc->vncdpy.w = 0; + vnc->vncdpy.h = 0; + free(vnc->tex_data); + vnc->tex_data = NULL; + } + + vnc->vncdpy.w = width; + vnc->vncdpy.h = height; + + if (!using_gl) { + /* init X11 */ + vnc->ximage = x11_create_ximage(vnc->dpy, vnc->vncdpy.w, vnc->vncdpy.h, &vnc->shm); + if (NULL == vnc->ximage) { + fprintf(stderr, "Oops: creating ximage failed\n"); + return; + } + + vnc->client->width = + vnc->ximage->bytes_per_line / (vnc->ximage->bits_per_pixel / 8); + vnc->client->frameBuffer = (void*)vnc->ximage->data; + + vnc->client->format.bitsPerPixel = vnc->ximage->bits_per_pixel; + vnc->client->format.redShift = x11_red_shift; + vnc->client->format.greenShift = x11_green_shift; + vnc->client->format.blueShift = x11_blue_shift; + vnc->client->format.redMax = (1 << x11_red_bits) - 1; + vnc->client->format.greenMax = (1 << x11_green_bits) - 1; + vnc->client->format.blueMax = (1 << x11_blue_bits) - 1; + } else { + /* init OpenGL */ + void *dummy; + int i; + + /* figure texture size (power of two) */ + for (i = 0; vnc->vncdpy.w >= (1 << i); i++) + ; + vnc->texture.w = (1 << i); + for (i = 0; vnc->vncdpy.h >= (1 << i); i++) + ; + vnc->texture.h = (1 << i); + if (vnc->debug) + fprintf(stderr,"%s: client %dx%d, tex %dx%d\n", __FUNCTION__, + vnc->vncdpy.w, vnc->vncdpy.h, vnc->texture.w, vnc->texture.h); + + /* create texture */ + glGenTextures(1, &vnc->tex); + glBindTexture(GL_TEXTURE_2D, vnc->tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + dummy = malloc(vnc->texture.w * vnc->texture.h * 4); + memset(dummy, 128, vnc->texture.w * vnc->texture.h * 4); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, + vnc->texture.w, vnc->texture.h, 0, + GL_RGB, GL_UNSIGNED_BYTE, + dummy); + free(dummy); + + /* image buffer */ + vnc->tex_data = malloc(vnc->vncdpy.w * vnc->vncdpy.h * 4); + vnc->client->frameBuffer = vnc->tex_data; + + vnc->client->format.bitsPerPixel = 32; + vnc->client->format.redShift = 16; + vnc->client->format.greenShift = 8; + vnc->client->format.blueShift = 0; + vnc->client->format.redMax = 255; + vnc->client->format.greenMax = 255; + vnc->client->format.blueMax = 255; + } + + if (vnc->debug) + fprintf(stderr, "%s: SetFormatAndEncodings: %s\n", __FUNCTION__, + using_gl ? "GL" : "X11" ); + SetFormatAndEncodings(vnc->client); + vnc_window_conf(vnc); +} + static void dpy_resize_window(struct vnc_window *vnc) { + int using_gl; + vnc->vncoff.x = 0; vnc->vncoff.y = 0; - if (vnc->ximage) - x11_resize_window(vnc); - if (vnc->tex) - gl_resize_window(vnc); - dpy_redraw(vnc);; + using_gl = dpy_gl_check(vnc); + if ((vnc->tex && !using_gl) || + (vnc->ximage && using_gl)) { + /* switching display mode */ + dpy_setup(vnc, vnc->client->width, vnc->client->height, using_gl); + } else { + if (vnc->ximage) + x11_resize_window(vnc); + if (vnc->tex) + gl_resize_window(vnc); + dpy_redraw(vnc); + } } /* ------------------------------------------------------------------ */ @@ -529,7 +639,6 @@ static void ungrab_input(struct vnc_window *vnc, guint32 time) static rfbBool vnc_resize(rfbClient* client) { struct vnc_window *vnc = rfbClientGetClientData(client, vnc_open); - int using_gl = 0; if (vnc->debug) fprintf(stderr, "%s: %dx%d\n", @@ -541,98 +650,7 @@ static rfbBool vnc_resize(rfbClient* client) return TRUE; } - /* cleanup */ - if (vnc->ximage) { - x11_destroy_ximage(vnc->dpy, vnc->ximage, vnc->shm); - vnc->ximage = NULL; - } - if (vnc->tex) { - /* FIXME: release texture */ - vnc->tex = 0; - vnc->vncdpy.w = 0; - vnc->vncdpy.h = 0; - free(vnc->tex_data); - vnc->tex_data = NULL; - } - - vnc->vncdpy.w = client->width; - vnc->vncdpy.h = client->height; - - /* opengl check */ - if (vnc->have_gl && vnc->vncdpy.w < vnc->tex_max && vnc->vncdpy.h < vnc->tex_max) { - if (vnc->gl_allways) - using_gl = 1; - if (vnc->gl_fullscreen && vnc->fullscreen) - using_gl = 1; - } - - if (!using_gl) { - /* init X11 */ - vnc->ximage = x11_create_ximage(vnc->dpy, vnc->vncdpy.w, vnc->vncdpy.h, &vnc->shm); - if (NULL == vnc->ximage) { - fprintf(stderr, "Oops: creating ximage failed\n"); - goto out; - } - - client->width = vnc->ximage->bytes_per_line / (vnc->ximage->bits_per_pixel / 8); - client->frameBuffer = (void*)vnc->ximage->data; - - client->format.bitsPerPixel = vnc->ximage->bits_per_pixel; - client->format.redShift = x11_red_shift; - client->format.greenShift = x11_green_shift; - client->format.blueShift = x11_blue_shift; - client->format.redMax = (1 << x11_red_bits) - 1; - client->format.greenMax = (1 << x11_green_bits) - 1; - client->format.blueMax = (1 << x11_blue_bits) - 1; - } else { - /* init OpenGL */ - void *dummy; - int i; - - /* figure texture size (power of two) */ - for (i = 0; vnc->vncdpy.w >= (1 << i); i++) - ; - vnc->texture.w = (1 << i); - for (i = 0; vnc->vncdpy.h >= (1 << i); i++) - ; - vnc->texture.h = (1 << i); - if (vnc->debug) - fprintf(stderr,"%s: client %dx%d, tex %dx%d\n", __FUNCTION__, - vnc->vncdpy.w, vnc->vncdpy.h, vnc->texture.w, vnc->texture.h); - - /* create texture */ - glGenTextures(1, &vnc->tex); - glBindTexture(GL_TEXTURE_2D, vnc->tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - dummy = malloc(vnc->texture.w * vnc->texture.h * 4); - memset(dummy, 128, vnc->texture.w * vnc->texture.h * 4); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, - vnc->texture.w, vnc->texture.h, 0, - GL_RGB, GL_UNSIGNED_BYTE, - dummy); - free(dummy); - - /* image buffer */ - vnc->tex_data = malloc(vnc->vncdpy.w * vnc->vncdpy.h * 4); - client->frameBuffer = vnc->tex_data; - - client->format.bitsPerPixel = 32; - client->format.redShift = 16; - client->format.greenShift = 8; - client->format.blueShift = 0; - client->format.redMax = 255; - client->format.greenMax = 255; - client->format.blueMax = 255; - } - - if (vnc->debug) - fprintf(stderr, "%s: SetFormatAndEncodings: %s\n", __FUNCTION__, - using_gl ? "GL" : "X11" ); - SetFormatAndEncodings(client); - vnc_window_conf(vnc); - - out: + dpy_setup(vnc, client->width, client->height, dpy_gl_check(vnc)); return TRUE; } |