diff options
Diffstat (limited to 'vnc.c')
-rw-r--r-- | vnc.c | 76 |
1 files changed, 64 insertions, 12 deletions
@@ -65,7 +65,8 @@ struct vnc_window { int have_gl; GLuint tex; int tex_max; - void *tex_data; + unsigned char *tex_data; + unsigned int dirty_y1, dirty_y2; /* config */ int fullscreen; @@ -175,7 +176,7 @@ static void gl_resize_window(struct vnc_window *vnc) vnc->redraw++; } -static void gl_blit(struct vnc_window *vnc) +static void gl_blit(struct vnc_window *vnc, int y1, int y2) { Window win = gdk_x11_drawable_get_xid(vnc->draw->window); float x,y; @@ -184,12 +185,18 @@ static void gl_blit(struct vnc_window *vnc) if (!vnc->tex) return; + + if (y1 > vnc->vncdpy.h) + y1 = vnc->vncdpy.h; + if (y2 > vnc->vncdpy.h) + y2 = vnc->vncdpy.h; + glBindTexture(GL_TEXTURE_2D, vnc->tex); glTexSubImage2D(GL_TEXTURE_2D, 0, - 0,0, vnc->vncdpy.w, vnc->vncdpy.h, + 0,y1, vnc->vncdpy.w, y2 - y1, GL_BGRA_EXT /* GL_RGB */, GL_UNSIGNED_BYTE, - vnc->tex_data); + vnc->tex_data + y1 * 4 * vnc->vncdpy.w); x = (float)vnc->vncdpy.w / vnc->texture.w; y = (float)vnc->vncdpy.h / vnc->texture.h; @@ -205,9 +212,34 @@ static void gl_blit(struct vnc_window *vnc) glDisable(GL_TEXTURE_2D); } +static void gl_update_vnc(struct vnc_window *vnc, + int x, int y, int w, int h) +{ + if (vnc->dirty_y1 > y) + vnc->dirty_y1 = y; + if (vnc->dirty_y2 < y+h) + vnc->dirty_y2 = y+h; + vnc->updates++; +} + +static void gl_update_win(struct vnc_window *vnc, + int x, int y, int w, int h) +{ + vnc->dirty_y1 = 0; + vnc->dirty_y2 = vnc->vncdpy.h; + vnc->updates++; +} + static void gl_flush(struct vnc_window *vnc) { - gl_blit(vnc); + if (vnc->redraw) { + vnc->dirty_y1 = 0; + vnc->dirty_y2 = vnc->vncdpy.h; + } + gl_blit(vnc, vnc->dirty_y1, vnc->dirty_y2); + + vnc->dirty_y1 = 99999; + vnc->dirty_y2 = 0; vnc->updates = 0; vnc->redraw = 0; } @@ -251,7 +283,8 @@ static void x11_update(struct vnc_window *vnc, static void x11_flush(struct vnc_window *vnc) { - x11_update(vnc, 0, 0, vnc->vncdpy.w, vnc->vncdpy.w); + if (vnc->redraw) + x11_update(vnc, 0, 0, vnc->vncdpy.w, vnc->vncdpy.w); vnc->updates = 0; vnc->redraw = 0; } @@ -259,8 +292,9 @@ static void x11_flush(struct vnc_window *vnc) /* ------------------------------------------------------------------ */ /* x11/gl wrappers */ -static void dpy_update(struct vnc_window *vnc, - int x, int y, int w, int h) +/* vnc display coordinates */ +static void dpy_update_vnc(struct vnc_window *vnc, + int x, int y, int w, int h) { if (vnc->debug) fprintf(stderr, "%s: mode%s%s, %dx%d+%d+%d\n", __FUNCTION__, @@ -270,7 +304,22 @@ static void dpy_update(struct vnc_window *vnc, if (vnc->ximage) x11_update(vnc, x, y, w, h); if (vnc->tex) - vnc->updates++; + gl_update_vnc(vnc, x, y, w, h); +} + +/* app window coordinates */ +static void dpy_update_win(struct vnc_window *vnc, + int x, int y, int w, int h) +{ + if (vnc->debug) + fprintf(stderr, "%s: mode%s%s, %dx%d+%d+%d\n", __FUNCTION__, + vnc->tex ? " GL" : "", + vnc->ximage ? " X11" : "", + w, h, x, y); + if (vnc->ximage) + x11_update(vnc, x, y, w, h); + if (vnc->tex) + gl_update_win(vnc, x, y, w, h); } static void dpy_redraw(struct vnc_window *vnc) @@ -557,7 +606,7 @@ static void vnc_update(rfbClient* cl, int x, int y, int w, int h) if (!GTK_WIDGET_DRAWABLE(vnc->draw)) return; - dpy_update(vnc, x,y, w,h); + dpy_update_vnc(vnc, x,y, w,h); } #ifdef HAVE_VNC_TEXT @@ -676,8 +725,8 @@ static gboolean expose_cb(GtkWidget *widget, GdkEventExpose *event, gpointer dat { struct vnc_window *vnc = data; - dpy_update(vnc, event->area.x, event->area.y, - event->area.width, event->area.height); + dpy_update_win(vnc, event->area.x, event->area.y, + event->area.width, event->area.height); if (0 == event->count) dpy_flush(vnc, __FUNCTION__); return TRUE; @@ -944,8 +993,11 @@ GtkWidget *vnc_open(char *hostname, int tcpport, unsigned long flags, vnc->viewonly = (flags & VNC_FLAG_VIEW_ONLY); vnc->debug = debug_level; debug_libvnc = debug_level; + snprintf(vnc->display, sizeof(vnc->display), "%s:%d", hostname, tcpport - 5900); + vnc->dirty_y1 = 99999; + vnc->dirty_y2 = 0; /* x11 */ vnc->dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default()); |