diff options
Diffstat (limited to 'x11vnc/screen.c')
-rw-r--r-- | x11vnc/screen.c | 162 |
1 files changed, 131 insertions, 31 deletions
diff --git a/x11vnc/screen.c b/x11vnc/screen.c index 1c21ed3..5b58375 100644 --- a/x11vnc/screen.c +++ b/x11vnc/screen.c @@ -29,12 +29,13 @@ void set_colormap(int reset); void set_nofb_params(int restore); void set_raw_fb_params(int restore); void do_new_fb(int reset_mem); -void free_old_fb(char *old_main, char *old_rfb, char *old_8to24, char *old_snap_fb); +void free_old_fb(void); void check_padded_fb(void); void install_padded_fb(char *geom); XImage *initialize_xdisplay_fb(void); void parse_scale_string(char *str, double *factor, int *scaling, int *blend, int *nomult4, int *pad, int *interpolate, int *numer, int *denom); +int parse_rotate_string(char *str, int *mode); int scale_round(int len, double fac); void initialize_screen(int *argc, char **argv, XImage *fb); void set_vnc_desktop_name(void); @@ -657,24 +658,34 @@ static void nofb_hook(rfbClientPtr cl) { screen->displayHook = NULL; } -void free_old_fb(char *old_main, char *old_rfb, char *old_8to24, char *old_snap_fb) { - if (old_main) { - free(old_main); - } - if (old_rfb) { - if (old_rfb != old_main) { - free(old_rfb); +void free_old_fb(void) { + char *fbs[16]; + int i, j, nfb = 0, db = 0; + + fbs[nfb++] = main_fb; main_fb = NULL; + fbs[nfb++] = rfb_fb; rfb_fb = NULL; + fbs[nfb++] = cmap8to24_fb; cmap8to24_fb = NULL; + fbs[nfb++] = snap_fb; snap_fb = NULL; + fbs[nfb++] = rot_fb; rot_fb = NULL; + fbs[nfb++] = raw_fb; raw_fb = NULL; + + for (i=0; i < nfb; i++) { + char *fb = fbs[i]; + int freeit = 1; + if (! fb || fb < (char *) 0x10) { + continue; } - } - if (old_8to24) { - if (old_8to24 != old_main && old_8to24 != old_rfb) { - free(old_8to24); + for (j=0; j < i; j++) { + if (fb == fbs[j]) { + freeit = 0; + break; + } } - } - if (old_snap_fb) { - if (old_snap_fb != old_main && old_snap_fb != old_rfb && - old_snap_fb != old_8to24) { - free(old_snap_fb); + if (freeit) { + if (db) fprintf(stderr, "free: %i %p\n", i, fb); + free(fb); + } else { + if (db) fprintf(stderr, "skip: %i %p\n", i, fb); } } } @@ -694,15 +705,7 @@ void do_new_fb(int reset_mem) { free_tiles(); } - free_old_fb(main_fb, rfb_fb, cmap8to24_fb, snap_fb); - - if (raw_fb == main_fb || raw_fb == rfb_fb) { - raw_fb = NULL; - } - main_fb = NULL; - rfb_fb = NULL; - cmap8to24_fb = NULL; - snap_fb = NULL; + free_old_fb(); fb = initialize_xdisplay_fb(); @@ -1766,6 +1769,35 @@ void parse_scale_string(char *str, double *factor, int *scaling, int *blend, free(tstr); } +int parse_rotate_string(char *str, int *mode) { + int m = ROTATE_NONE; + if (str == NULL || !strcmp(str, "") || !strcmp(str, "0")) { + m = ROTATE_NONE; + } else if (!strcmp(str, "x")) { + m = ROTATE_X; + } else if (!strcmp(str, "y")) { + m = ROTATE_Y; + } else if (!strcmp(str, "xy") || !strcmp(str, "yx") || + !strcmp(str,"+180") || !strcmp(str,"-180") || !strcmp(str,"180")) { + m = ROTATE_XY; + } else if (!strcmp(str, "+90") || !strcmp(str, "90")) { + m = ROTATE_90; + } else if (!strcmp(str, "+90x") || !strcmp(str, "90x")) { + m = ROTATE_90X; + } else if (!strcmp(str, "+90y") || !strcmp(str, "90y")) { + m = ROTATE_90Y; + } else if (!strcmp(str, "-90") || !strcmp(str, "270") || + !strcmp(str, "+270")) { + m = ROTATE_270; + } else { + rfbLog("invalid -rotate mode: %s\n", str); + } + if (mode) { + *mode = m; + } + return m; +} + int scale_round(int len, double fac) { double eps = 0.000001; @@ -1837,6 +1869,28 @@ static void setup_scaling(int *width_in, int *height_in) { } } +static void setup_rotating(void) { + char *rs = rotating_str; + + rotating_cursors = 1; + if (rs && strstr(rs, "nc:") == rs) { + rs += strlen("nc:"); + rotating_cursors = 0; + } + + rotating = parse_rotate_string(rs, NULL); + if (! rotating) { + rotating_cursors = 0; + } + + if (rotating == ROTATE_90 || rotating == ROTATE_90X || + rotating == ROTATE_90Y || rotating == ROTATE_270) { + rotating_same = 0; + } else { + rotating_same = 1; + } +} + /* * initialize the rfb framebuffer/screen */ @@ -1892,8 +1946,27 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { rfb_bytes_per_line = main_bytes_per_line; } + setup_rotating(); + + if (rotating) { + if (! rotating_same) { + int t, b = main_bytes_per_line / fb->width; + if (scaling) { + rot_bytes_per_line = b * height; + } else { + rot_bytes_per_line = b * fb->height; + } + t = width; + width = height; /* The big swap... */ + height = t; + } else { + rot_bytes_per_line = rfb_bytes_per_line; + } + } + if (cmap8to24 && depth == 8) { rfb_bytes_per_line *= 4; + rot_bytes_per_line *= 4; } /* @@ -1965,7 +2038,11 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { } /* set up format from scratch: */ - screen->paddedWidthInBytes = rfb_bytes_per_line; + if (rotating && ! rotating_same) { + screen->paddedWidthInBytes = rot_bytes_per_line; + } else { + screen->paddedWidthInBytes = rfb_bytes_per_line; + } screen->serverFormat.bitsPerPixel = fb_bpp; screen->serverFormat.depth = fb_depth; screen->serverFormat.trueColour = TRUE; @@ -2155,6 +2232,8 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { main_bytes_per_line); fprintf(stderr, " rfb_fb_bytes_per_line: %d\n", rfb_bytes_per_line); + fprintf(stderr, " rot_fb_bytes_per_line: %d\n", + rot_bytes_per_line); switch(fb->format) { case XYBitmap: fprintf(stderr, " format: XYBitmap\n"); break; @@ -2201,11 +2280,13 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { main_fb = NULL; rfb_fb = main_fb; cmap8to24_fb = NULL; + rot_fb = NULL; screen->displayHook = nofb_hook; } else { main_fb = fb->data; rfb_fb = NULL; cmap8to24_fb = NULL; + rot_fb = NULL; if (cmap8to24) { int n = main_bytes_per_line * fb->height; @@ -2215,20 +2296,39 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { cmap8to24_fb = (char *) malloc(n); memset(cmap8to24_fb, 0, n); } + + if (rotating) { + int n = rot_bytes_per_line * height; + rot_fb = (char *) malloc(n); + memset(rot_fb, 0, n); + } + if (scaling) { - rfb_fb = (char *) malloc(rfb_bytes_per_line * height); - memset(rfb_fb, 0, rfb_bytes_per_line * height); + int n = rfb_bytes_per_line * height; + + if (rotating && ! rotating_same) { + n = rot_bytes_per_line * height; + } + + rfb_fb = (char *) malloc(n); + memset(rfb_fb, 0, n); + } else if (cmap8to24) { rfb_fb = cmap8to24_fb; } else { rfb_fb = main_fb; } } - screen->frameBuffer = rfb_fb; + if (rot_fb) { + screen->frameBuffer = rot_fb; + } else { + screen->frameBuffer = rfb_fb; + } if (!quiet) { fprintf(stderr, " rfb_fb: %p\n", rfb_fb); fprintf(stderr, " main_fb: %p\n", main_fb); fprintf(stderr, " 8to24_fb: %p\n", cmap8to24_fb); + fprintf(stderr, " rot_fb: %p\n", rot_fb); fprintf(stderr, " snap_fb: %p\n", snap_fb); fprintf(stderr, " raw_fb: %p\n", raw_fb); fprintf(stderr, " fake_fb: %p\n", fake_fb); @@ -2241,7 +2341,7 @@ void initialize_screen(int *argc, char **argv, XImage *fb) { setup_cursors_and_push(); - if (scaling || cmap8to24) { + if (scaling || rotating || cmap8to24) { mark_rect_as_modified(0, 0, dpy_x, dpy_y, 0); } |