diff options
author | Tatsuya Kinoshita <tats@debian.org> | 2021-01-02 00:20:37 +0000 |
---|---|---|
committer | Tatsuya Kinoshita <tats@debian.org> | 2021-01-02 00:20:37 +0000 |
commit | 1d0ba25a660483da1272a31dd077ed94441e3d9f (patch) | |
tree | 1d8dee52cd1e3d340fe178a8193dc96c4496db84 /w3mimg/x11/x11_w3mimg.c | |
parent | Merge branch 'cvstrunk' into upstream (diff) | |
download | w3m-upstream/0.5.3+git20210102.tar.gz w3m-upstream/0.5.3+git20210102.zip |
New upstream version 0.5.3+git20210102upstream/0.5.3+git20210102upstream
Diffstat (limited to 'w3mimg/x11/x11_w3mimg.c')
-rw-r--r-- | w3mimg/x11/x11_w3mimg.c | 92 |
1 files changed, 77 insertions, 15 deletions
diff --git a/w3mimg/x11/x11_w3mimg.c b/w3mimg/x11/x11_w3mimg.c index f5be4a8..9a539de 100644 --- a/w3mimg/x11/x11_w3mimg.c +++ b/w3mimg/x11/x11_w3mimg.c @@ -14,7 +14,7 @@ #elif defined(USE_GDKPIXBUF) #if defined(USE_GTK2) #include <glib-object.h> -#include <gdk/gdk.h> +#include <gdk-pixbuf/gdk-pixbuf.h> #include <gdk-pixbuf-xlib/gdk-pixbuf-xlib.h> #else #include <gdk-pixbuf/gdk-pixbuf-xlib.h> @@ -121,24 +121,32 @@ x11_init(w3mimg_op * self) if (self == NULL) return 0; xi = (struct x11_info *)self->priv; +#if defined(USE_IMLIB) if (xi == NULL) return 0; -#if defined(USE_IMLIB) if (!xi->id) { xi->id = Imlib_init(xi->display); if (!xi->id) return 0; } #elif defined(USE_GDKPIXBUF) - if (!xi->init_flag) { + if (!xi) { +#if defined(USE_GTK2) + g_type_init(); +#endif + } + else if (!xi->init_flag) { + XWindowAttributes attr; #if defined(USE_GTK2) g_type_init(); #endif - gdk_pixbuf_xlib_init(xi->display, 0); + XGetWindowAttributes(xi->display, xi->parent, &attr); + /* gdk_pixbuf_xlib_init_with_depth() ignores depth, sigh... */ + gdk_pixbuf_xlib_init_with_depth(xi->display, 0, attr.depth); xi->init_flag = TRUE; } #endif - if (!xi->imageGC) { + if (xi && !xi->imageGC) { xi->imageGC = XCreateGC(xi->display, xi->parent, 0, NULL); if (!xi->imageGC) return 0; @@ -200,14 +208,16 @@ x11_set_background(w3mimg_op * self, char *background) { XColor screen_def, exact_def; struct x11_info *xi; + XWindowAttributes attr; if (self == NULL) return; xi = (struct x11_info *)self->priv; if (xi == NULL) return; + XGetWindowAttributes(xi->display, xi->window, &attr); if (background && - XAllocNamedColor(xi->display, DefaultColormap(xi->display, 0), + XAllocNamedColor(xi->display, attr.colormap, background, &screen_def, &exact_def)) xi->background_pixel = screen_def.pixel; else { @@ -216,7 +226,7 @@ x11_set_background(w3mimg_op * self, char *background) XImage *i; p = XCreatePixmap(xi->display, xi->window, 1, 1, - DefaultDepth(xi->display, 0)); + attr.depth); gc = XCreateGC(xi->display, xi->window, 0, NULL); if (!p || !gc) exit(1); /* XXX */ @@ -258,6 +268,7 @@ x11_img_new(struct x11_info *xi, int w, int h, int n) { struct x11_image *img = NULL; int i; + XWindowAttributes attr; img = malloc(sizeof(*img)); if (!img) @@ -267,9 +278,10 @@ x11_img_new(struct x11_info *xi, int w, int h, int n) if (!img->pixmap) goto ERROR; + XGetWindowAttributes(xi->display, xi->window, &attr); for (i = 0; i < n; i++) { img->pixmap[i] = XCreatePixmap(xi->display, xi->parent, w, h, - DefaultDepth(xi->display, 0)); + attr.depth); if (!img->pixmap[i]) goto ERROR; @@ -318,6 +330,41 @@ resize_image(GdkPixbuf * pixbuf, int width, int height) return NULL; return resized_pixbuf; } + +#if defined(USE_GTK2) +static void +render_pixbuf_to_pixmap_32(Display *display, GC gc, Pixmap pixmap, GdkPixbuf * pixbuf) +{ + unsigned int x, y, width, height, rowstride, bytes_per_pixel; + unsigned char *line; + XImage *image; + + width = gdk_pixbuf_get_width(pixbuf) ; + height = gdk_pixbuf_get_height(pixbuf) ; + + if (!(image = XGetImage(display, pixmap, 0, 0, width, height, AllPlanes, ZPixmap))) + return ; + + bytes_per_pixel = (gdk_pixbuf_get_has_alpha(pixbuf)) ? 4 : 3; + rowstride = gdk_pixbuf_get_rowstride(pixbuf); + line = gdk_pixbuf_get_pixels(pixbuf); + + for (y = 0; y < height; y++) { + u_char *pixel; + + pixel = line; + for (x = 0; x < width; x++) { + XPutPixel(image, x, y, + (pixel[0] <<16) | (pixel[1] <<8) | pixel[2] | 0xff000000); + pixel += bytes_per_pixel; + } + line += rowstride; + } + + XPutImage(display, pixmap, gc, image, 0, 0, 0, 0, width, height); + XDestroyImage(image); +} +#endif #endif static int @@ -342,6 +389,7 @@ x11_load_image(w3mimg_op * self, W3MImage * img, char *fname, int w, int h) GList *frames; #endif #endif + XWindowAttributes attr; if (self == NULL) return 0; @@ -349,6 +397,7 @@ x11_load_image(w3mimg_op * self, W3MImage * img, char *fname, int w, int h) if (xi == NULL) return 0; + XGetWindowAttributes(xi->display, xi->window, &attr); #if defined(USE_IMLIB) im = Imlib_load_image(xi->id, fname); if (!im) @@ -358,7 +407,7 @@ x11_load_image(w3mimg_op * self, W3MImage * img, char *fname, int w, int h) if (h <= 0) h = im->rgb_height; img->pixmap = (void *)XCreatePixmap(xi->display, xi->parent, w, h, - DefaultDepth(xi->display, 0)); + attr.depth); if (!img->pixmap) return 0; XSetForeground(xi->display, xi->imageGC, xi->background_pixel); @@ -374,17 +423,21 @@ x11_load_image(w3mimg_op * self, W3MImage * img, char *fname, int w, int h) w = imlib_image_get_width(); if (h <= 0) h = imlib_image_get_height(); + + im = imlib_create_cropped_scaled_image(0, 0, imlib_image_get_width(), imlib_image_get_height(), w, h); + imlib_context_set_image(im); + img->pixmap = (void *)XCreatePixmap(xi->display, xi->parent, w, h, - DefaultDepth(xi->display, 0)); + attr.depth); if (!img->pixmap) return 0; XSetForeground(xi->display, xi->imageGC, xi->background_pixel); XFillRectangle(xi->display, (Pixmap) img->pixmap, xi->imageGC, 0, 0, w, h); imlib_context_set_display(xi->display); - imlib_context_set_visual(DefaultVisual(xi->display, 0)); - imlib_context_set_colormap(DefaultColormap(xi->display, 0)); + imlib_context_set_visual(attr.visual); + imlib_context_set_colormap(attr.colormap); imlib_context_set_drawable((Drawable) img->pixmap); - imlib_render_image_on_drawable_at_size(0, 0, w, h); + imlib_render_image_on_drawable(0, 0); imlib_free_image(); #elif defined(USE_GDKPIXBUF) max_anim = self->max_anim; @@ -416,7 +469,7 @@ x11_load_image(w3mimg_op * self, W3MImage * img, char *fname, int w, int h) ratio_h = 1.0 * h / ih; } tmp_pixmap = XCreatePixmap(xi->display, xi->parent, w, h, - DefaultDepth(xi->display, 0)); + attr.depth); XSetForeground(xi->display, xi->imageGC, xi->background_pixel); XFillRectangle(xi->display, (Pixmap) tmp_pixmap, xi->imageGC, 0, 0, w, h); if (!tmp_pixmap) { @@ -459,7 +512,10 @@ x11_load_image(w3mimg_op * self, W3MImage * img, char *fname, int w, int h) if (delay > ximg->delay) ximg->delay = delay; - gdk_pixbuf_xlib_render_to_drawable_alpha(pixbuf, + if (attr.depth == 32) + render_pixbuf_to_pixmap_32(xi->display, xi->imageGC, ximg->pixmap[j], pixbuf); + else + gdk_pixbuf_xlib_render_to_drawable_alpha(pixbuf, (Drawable) ximg->pixmap[j], 0, 0, 0, 0, w, h, GDK_PIXBUF_ALPHA_BILEVEL, 1, @@ -653,9 +709,11 @@ x11_get_image_size(w3mimg_op * self, W3MImage * img, char *fname, int *w, if (self == NULL) return 0; +#if defined(USE_IMLIB) && defined(USE_IMLIB2) xi = (struct x11_info *)self->priv; if (xi == NULL) return 0; +#endif #if defined(USE_IMLIB) im = Imlib_load_image(xi->id, fname); @@ -755,6 +813,9 @@ w3mimg_x11open() return NULL; memset(wop, 0, sizeof(w3mimg_op)); + if (getenv("W3M_USE_REMOTE_IMAGE")) + goto end; + xi = (struct x11_info *)malloc(sizeof(struct x11_info)); if (xi == NULL) goto error; @@ -807,6 +868,7 @@ w3mimg_x11open() wop->priv = xi; + end: wop->init = x11_init; wop->finish = x11_finish; wop->active = x11_active; |