📄 x11_w3mimg.c
字号:
/* $Id: x11_w3mimg.c,v 1.25 2003/07/13 16:19:10 ukai Exp $ */#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include "config.h"#if defined(USE_IMLIB)#include <Imlib.h>#elif defined(USE_IMLIB2)#include <X11/Xlib.h>#include <X11/Xutil.h>#include <Imlib2.h>#elif defined(USE_GDKPIXBUF)#include <gdk-pixbuf/gdk-pixbuf-xlib.h>#else#error no Imlib and GdkPixbuf support#endif#include "w3mimg/w3mimg.h"#define OFFSET_X 2#define OFFSET_Y 2struct x11_info { Display *display; Window window, parent; unsigned long background_pixel; GC imageGC;#if defined(USE_IMLIB) ImlibData *id;#elif defined(USE_GDKPIXBUF) int init_flag;#endif};#if defined(USE_GDKPIXBUF)struct x11_image { int total; int no; int wait; int delay; Pixmap *pixmap;};static voidget_animation_size(GdkPixbufAnimation * animation, int *w, int *h, int *delay){ GList *frames; int iw, ih, n, i, d = -1; frames = gdk_pixbuf_animation_get_frames(animation); n = gdk_pixbuf_animation_get_num_frames(animation); *w = gdk_pixbuf_animation_get_width(animation); *h = gdk_pixbuf_animation_get_height(animation); for (i = 0; i < n; i++) { GdkPixbufFrame *frame; GdkPixbuf *pixbuf; int tmp; frame = (GdkPixbufFrame *) g_list_nth_data(frames, i); tmp = gdk_pixbuf_frame_get_delay_time(frame); if (tmp > d) d = tmp; pixbuf = gdk_pixbuf_frame_get_pixbuf(frame); iw = gdk_pixbuf_frame_get_x_offset(frame) + gdk_pixbuf_get_width(pixbuf); ih = gdk_pixbuf_frame_get_y_offset(frame) + gdk_pixbuf_get_height(pixbuf); if (iw > *w) *w = iw; if (ih > *h) *h = ih; } if (delay) *delay = d;}#endifstatic intx11_init(w3mimg_op * self){ struct x11_info *xi; if (self == NULL) return 0; xi = (struct x11_info *)self->priv; 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) { gdk_pixbuf_xlib_init(xi->display, 0); xi->init_flag = TRUE; }#endif if (!xi->imageGC) { xi->imageGC = XCreateGC(xi->display, xi->parent, 0, NULL); if (!xi->imageGC) return 0; } return 1;}static intx11_finish(w3mimg_op * self){ struct x11_info *xi; if (self == NULL) return 0; xi = (struct x11_info *)self->priv; if (xi == NULL) return 0; if (xi->imageGC) { XFreeGC(xi->display, xi->imageGC); xi->imageGC = NULL; } return 1;}static intx11_clear(w3mimg_op * self, int x, int y, int w, int h){ struct x11_info *xi; if (self == NULL) return 0; xi = (struct x11_info *)self->priv; if (xi == NULL) return 0; if (x < 0) x = 0; if (y < 0) y = 0; XClearArea(xi->display, xi->window, x, y, w, h, False); return 1;}static intx11_active(w3mimg_op * self){ struct x11_info *xi; if (self == NULL) return 0; xi = (struct x11_info *)self->priv; if (xi == NULL) return 0; if (!xi->imageGC) return 0; return 1;}static voidx11_set_background(w3mimg_op * self, char *background){ XColor screen_def, exact_def; struct x11_info *xi; if (self == NULL) return; xi = (struct x11_info *)self->priv; if (xi == NULL) return; if (background && XAllocNamedColor(xi->display, DefaultColormap(xi->display, 0), background, &screen_def, &exact_def)) xi->background_pixel = screen_def.pixel; else { Pixmap p; GC gc; XImage *i; p = XCreatePixmap(xi->display, xi->window, 1, 1, DefaultDepth(xi->display, 0)); gc = XCreateGC(xi->display, xi->window, 0, NULL); if (!p || !gc) exit(1); /* XXX */ XCopyArea(xi->display, xi->window, p, gc, (self->offset_x >= 1) ? (self->offset_x - 1) : 0, (self->offset_y >= 1) ? (self->offset_y - 1) : 0, 1, 1, 0, 0); i = XGetImage(xi->display, p, 0, 0, 1, 1, -1, ZPixmap); if (!i) exit(1); xi->background_pixel = XGetPixel(i, 0, 0); XDestroyImage(i); XFreeGC(xi->display, gc); XFreePixmap(xi->display, p); }}static voidx11_sync(w3mimg_op * self){ struct x11_info *xi; if (self == NULL) return; xi = (struct x11_info *)self->priv; if (xi == NULL) return; XSync(xi->display, False);}static voidx11_close(w3mimg_op * self){ /* XCloseDisplay(xi->display); */}#if defined(USE_GDKPIXBUF)static struct x11_image *x11_img_new(struct x11_info *xi, int w, int h, int n){ struct x11_image *img = NULL; int i; img = malloc(sizeof(*img)); if (!img) goto ERROR; img->pixmap = calloc(n, sizeof(*(img->pixmap))); if (!img->pixmap) goto ERROR; for (i = 0; i < n; i++) { img->pixmap[i] = XCreatePixmap(xi->display, xi->parent, w, h, DefaultDepth(xi->display, 0)); if (!img->pixmap[i]) goto ERROR; XSetForeground(xi->display, xi->imageGC, xi->background_pixel); XFillRectangle(xi->display, (Pixmap) img->pixmap[i], xi->imageGC, 0, 0, w, h); } img->no = 0; img->total = n; img->wait = 0; img->delay = -1; return img; ERROR: if (img) { if (img->pixmap) { for (i = 0; i < n; i++) { if (img->pixmap[i]) XFreePixmap(xi->display, (Pixmap) img->pixmap[i]); } free(img->pixmap); } free(img); } return NULL;}static GdkPixbuf *resize_image(GdkPixbuf * pixbuf, int width, int height){ GdkPixbuf *resized_pixbuf; int w, h; if (pixbuf == NULL) return NULL; w = gdk_pixbuf_get_width(pixbuf); h = gdk_pixbuf_get_height(pixbuf); if (width < 1 || height < 1) return pixbuf; if (w == width && h == height) return pixbuf; resized_pixbuf = gdk_pixbuf_scale_simple(pixbuf, width, height, GDK_INTERP_BILINEAR); if (resized_pixbuf == NULL) return NULL; return resized_pixbuf;}#endifstatic intx11_load_image(w3mimg_op * self, W3MImage * img, char *fname, int w, int h){ struct x11_info *xi;#if defined(USE_IMLIB) ImlibImage *im;#elif defined(USE_IMLIB2) Imlib_Image im;#elif defined(USE_GDKPIXBUF) GdkPixbufAnimation *animation; GList *frames; int i, j, iw, ih, n, frame_num, delay, max_anim; double ratio_w, ratio_h; struct x11_image *ximg; Pixmap tmp_pixmap;#endif if (self == NULL) return 0; xi = (struct x11_info *)self->priv; if (xi == NULL) return 0;#if defined(USE_IMLIB) im = Imlib_load_image(xi->id, fname); if (!im) return 0; if (w <= 0) w = im->rgb_width; if (h <= 0) h = im->rgb_height; img->pixmap = (void *)XCreatePixmap(xi->display, xi->parent, w, h, DefaultDepth(xi->display, 0)); 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_paste_image(xi->id, im, (Pixmap) img->pixmap, 0, 0, w, h); Imlib_kill_image(xi->id, im);#elif defined(USE_IMLIB2) im = imlib_load_image(fname); if (!im) return 0; imlib_context_set_image(im); if (w <= 0) w = imlib_image_get_width(); if (h <= 0) h = imlib_image_get_height(); img->pixmap = (void *)XCreatePixmap(xi->display, xi->parent, w, h, DefaultDepth(xi->display, 0)); 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_drawable((Drawable) img->pixmap); imlib_render_image_on_drawable_at_size(0, 0, w, h); imlib_free_image();#elif defined(USE_GDKPIXBUF) max_anim = self->max_anim; animation = gdk_pixbuf_animation_new_from_file(fname); if (!animation) return 0; frames = gdk_pixbuf_animation_get_frames(animation); frame_num = n = gdk_pixbuf_animation_get_num_frames(animation); get_animation_size(animation, &iw, &ih, &delay); if (delay <= 0) max_anim = -1; if (max_anim < 0) { frame_num = (-max_anim > n) ? n : -max_anim; } else if (max_anim > 0) { frame_num = n = (max_anim > n) ? n : max_anim; } if (w < 1 || h < 1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -