/* Scaling Pixmap. test 2. */ #include #include #include #include #include #include #include /* include xpm binary */ #include "bg01.xpm" #define XPM_W 640 #define XPM_H 360 #define XPM_NAME bg01_xpm /* #include "bg02.xpm" #define XPM_W 320 #define XPM_H 180 #define XPM_NAME bg02_xpm */ /* kind. 0: slow, 1: fast */ #define SCALING_KIND 1 #define WIN_X 0 #define WIN_Y 64 #define BORDER 0 #ifndef M_PI #define M_PI 3.14159265358979 #endif #define deg2rad(x) (x * M_PI / 180.0) /* get a color value from a color name */ static unsigned long get_color(Display *dpy, char *colorname) { Colormap cmap; XColor near_color, true_color; cmap = DefaultColormap(dpy, DefaultScreen(dpy)); XAllocNamedColor(dpy, cmap, colorname, &near_color, &true_color); return near_color.pixel; } /* scale Pixmap */ static void scale_pixmap(Display *dpy, Drawable win, Pixmap *src, Pixmap *dst, int src_w, int src_h, int dst_w, int dst_h) { GC gc; float xscale, yscale; int x, y; struct timespec start, end; double diff; xscale = (float)src_w / dst_w; yscale = (float)src_h / dst_h; gc = XCreateGC(dpy, win, 0, 0); XSetGraphicsExposures(dpy, gc, False); timespec_get(&start, TIME_UTC); switch (SCALING_KIND) { case 0: /* slow */ for (y = 0; y < dst_h; y++) { int sy = (int)(y * yscale); for (x = 0; x < dst_w; x++) XCopyArea(dpy, *src, *dst, gc, (int)(x * xscale), sy, 1, 1, x, y); } break; case 1: /* fast */ for (x = dst_w - 1; x >= 0; x--) XCopyArea(dpy, *src, *dst, gc, (int)(x * xscale), 0, 1, src_h, x, 0); for (y = dst_h - 1; y >= 0; y--) XCopyArea(dpy, *dst, *dst, gc, 0, (int)(y * yscale), dst_w, 1, 0, y); break; default: break; } XFreeGC(dpy, gc); timespec_get(&end, TIME_UTC); diff = (end.tv_sec + (double)end.tv_nsec / 1000000000) - (start.tv_sec + (double)start.tv_nsec / 1000000000); printf("%lf sec\n", diff); } /* update and draw */ static void update(Display *dpy, Drawable win, GC gc, Pixmap pix, Pixmap buf, int new_w, int new_h) { XWindowAttributes xgwa; int r, x, y; int scrw, scrh; /* get window attributes */ XGetWindowAttributes(dpy, win, &xgwa); scrw = xgwa.width; /* window width */ scrh = xgwa.height; /* window height */ scale_pixmap(dpy, win, &pix, &buf, XPM_W, XPM_H, new_w, new_h); /* centering */ x = scrw - ((scrw + new_w) / 2); y = scrh - ((scrh + new_h) / 2); /* clear window */ XClearWindow(dpy, win); /* draw image (Pixmap) */ XSetGraphicsExposures(dpy, gc, False); XCopyArea(dpy, buf, win, gc, 0, 0, new_w, new_h, x, y); } int main(void) { Display *dpy; Window root; Window win; int screen; int display_w, display_h; XEvent evt; unsigned long black, white; XWindowAttributes xgwa; GC gc; Pixmap pix; Pixmap buf; int busy_loop; double new_w, new_h; double dx; /* open display */ dpy = XOpenDisplay(NULL); root = DefaultRootWindow(dpy); screen = DefaultScreen(dpy); /* get display size */ display_w = DisplayWidth(dpy, screen); display_h = DisplayHeight(dpy, screen); printf("Screen: %d x %d\n", display_w, display_h); /* get color black and white */ white = WhitePixel(dpy, screen); black = BlackPixel(dpy, screen); /* create window */ win = XCreateSimpleWindow(dpy, root, WIN_X, WIN_Y, display_w, display_h, BORDER, white, black); XSelectInput(dpy, win, KeyPressMask | ExposureMask); XMapWindow(dpy, win); /* wait display window */ do { XNextEvent(dpy, &evt); } while (evt.type != Expose); XMoveWindow(dpy, win, WIN_X, WIN_Y); /* create graphics context */ gc = XCreateGC(dpy, win, 0, 0); XSetGraphicsExposures(dpy, gc, False); /* load image */ if (XpmCreatePixmapFromData(dpy, win, XPM_NAME, &pix, NULL, NULL)) { fprintf(stderr, "Error not load xpm."); return 1; } XSetForeground(dpy, gc, get_color(dpy, "green")); XGetWindowAttributes(dpy, win, &xgwa); buf = XCreatePixmap(dpy, win, display_w, display_h, xgwa.depth); XFillRectangle(dpy, buf, gc, 0, 0, display_w, display_h); new_w = display_w; new_h = display_h; dx = -6; busy_loop = 1; while (busy_loop) { /* event */ while (XPending(dpy)) { XNextEvent(dpy, &evt); switch (evt.type) { /* case Expose: if (evt.xexpose.count == 0) { } break; */ case KeyPress: busy_loop = 0; break; default: break; } } update(dpy, win, gc, pix, buf, new_w, new_h); new_w += dx; if (new_w <= 32) { new_w = 32; dx *= -1; } if (new_w >= display_w) { new_w = display_w; dx *= -1; } new_h = display_h * new_w / display_w; XFlush(dpy); usleep(16 * 1000); /* wait */ } XFreePixmap(dpy, pix); XFreePixmap(dpy, buf); XFreeGC(dpy, gc); XDestroyWindow(dpy, win); XCloseDisplay(dpy); return 0; }