代码拉取完成,页面将自动刷新
#include <stdint.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/cursorfont.h>
#include "util.h"
static Window create_window(Display *display, int screen, int w, int h, const char *title);
static char *load_image(const char * file, int *w, int *h);
static void draw(char *rgb_out, const char *rgb, int w, int h);
static void drawEx(char *dst, int dst_w, int dst_h, int dst_offset_x, int dst_offset_y,
const char *src, int src_w, int src_h, int src_offset_x, int src_offset_y);
unsigned char *read_jpeg(const char *file, int *w, int *h);
Atom wm_delete_message;
Cursor watch;
Cursor normal;
int main(int argc, char *argv[])
{
Bool run = True;
Window window = 0;
int ret = 0;
if (argc != 2)
{
printf("usage: %s <jpeg file>\n", argv[0]);
return 0;
}
Display* display = XOpenDisplay(NULL);
ASSERT_RET(0, "fail to open display\n", (NULL == display));
int screen = DefaultScreen(display);
Visual *visual = DefaultVisual(display, screen);
if (NULL == visual)
{
LOG("fail to open vitual\n");
XCloseDisplay(display);
return 0;
}
int depth = DefaultDepth(display, screen);
int scr_width = XDisplayWidth(display, screen);
int scr_height = XDisplayHeight(display, screen);
LOG("screen:(%dx%d)\n", scr_width, scr_height);
watch = XCreateFontCursor(display, XC_watch);
normal = XCreateFontCursor(display, XC_left_ptr);
GC gc = DefaultGC(display, screen);
XSetForeground(display, gc, BlackPixel(display, screen));
XSetBackground(display, gc, ORANGE);
wm_delete_message = XInternAtom(display, "WM_DELETE_WINDOW", False);
window = create_window(display, screen, scr_width, scr_height, "jpeg viewer");
if (0 >= window)
{
LOG("fail to create window\n");
goto done;
}
XImage *image = NULL;
int image_w = 0;
int image_h = 0;
int w,h;
char *data_image = load_image(argv[1], &image_w, &image_h);
if (NULL == data_image)
{
LOG("fail to load image\n");
goto done;
}
char *data = NULL;
XEvent event;
int off_x = 40;
int off_y = 60;
do
{
XNextEvent(display, &event);
switch (event.type)
{
case Expose:
{
if (NULL != image)
{
XPutImage(display, window, gc, image, 0,0,0,0, w, h);
//XFlush(display);
}
break;
}
case ConfigureNotify:
{
if (image == NULL || w != event.xconfigure.width || h != event.xconfigure.height)
{
if (NULL != image)
{
XDestroyImage(image);
image = NULL;
}
w = event.xconfigure.width;
h = event.xconfigure.height;
data = (char *) malloc(w * h * 4 );
if (NULL == data)
{
LOG("fail to alloc memory, size:%d\n", w*h*4);
break;
}
image = XCreateImage(display, visual, depth, ZPixmap, 0, data, w, h, 32, 0);
if (NULL == image)
{
LOG("fail to create x iamge\n");
break;
}
drawEx(data, w, h, off_x>=0?off_x:0, off_y>=0?off_y:0 ,
data_image, image_w, image_h, off_x<0?-off_x:0, off_y<0?-off_y:0);
}
break;
}
case ClientMessage:
{
if (event.xclient.data.l[0] == wm_delete_message)
{
run = False;
if (NULL != image)
{
XDestroyImage(image);
image = NULL;
}
}
break;
}
case KeyPress:
{
KeySym ks;
XLookupString(&event.xkey, NULL, 0, &ks, NULL);
if (ks == XK_Left)
{
off_x -= 20;
}
else if ( ks == XK_Right)
{
off_x += 20;
}
else if ( ks == XK_Up)
{
off_y -= 20;
}
else if (ks == XK_Down)
{
off_y += 20;
}
if (NULL != image)
{
drawEx(data, w, h, off_x>=0?off_x:0, off_y>=0?off_y:0 ,
data_image, image_w, image_h, off_x<0?-off_x:0, off_y<0?-off_y:0);
XPutImage(display, window, gc, image, 0,0,0,0, w, h);
XFlush(display);
}
}
default:
{
//LOG("invalid event type:%d\n", event.type);
break;
}
}
} while(run);
done:
if(data_image != NULL)
{
free(data_image);
}
if (NULL != image)
{
XDestroyImage(image);
}
XCloseDisplay(display);
return 0;
}
char *load_image(const char *file, int *w, int *h)
{
ASSERT_RET(NULL, "file is null\n", (file == NULL || h == NULL || w == NULL));
unsigned char *image = read_jpeg(file, w, h);
if(NULL == image)
{
//free((void *)(char *)image);
}
return image;
}
Window create_window(Display *display, int screen, int w, int h, const char *title)
{
ASSERT_RET(-1, "title is null\n", (title == NULL));
ASSERT_RET(-1, "display is null\n", (display == NULL));
Window root = DefaultRootWindow(display);
Window window = XCreateSimpleWindow(display, root,
0, 0, w, h, 0,
BlackPixel(display, screen),
WhitePixel(display, screen));
XSelectInput(display, window, ExposureMask | ButtonPressMask |
ButtonReleaseMask | KeyPressMask | PointerMotionMask | StructureNotifyMask);
XSetWMProtocols(display, window, &wm_delete_message, 1);
XStoreName(display, window, title);
XMapWindow(display, window);
return window;
}
void drawEx(char *dst, int dst_w, int dst_h, int dst_offset_x, int dst_offset_y,
const char *src, int src_w, int src_h, int src_offset_x, int src_offset_y)
{
int h = dst_offset_y < 0 ? 0 : dst_offset_y;
int i = src_offset_y < 0 ? 0 : src_offset_y;
memset(dst, 0xff, dst_w*dst_h * 4);
LOG("dst: %dx%d, off:(%d,%d), src: %dx%d, off:(%d,%d)\n", dst_w, dst_h, dst_offset_x,dst_offset_y,
src_w,src_h,src_offset_x,src_offset_y);
for (; h < dst_h && i < src_h; h++,i++)
{
int w = dst_offset_x < 0 ? 0 : dst_offset_x;
int j = src_offset_x < 0 ? 0 : src_offset_x;
for (; w < dst_w && j < src_w; w++,j++)
{
dst[(w + h * dst_w)*4+0] = src[(j+i*src_w)*3+2];
dst[(w + h * dst_w)*4+1] = src[(j+i*src_w)*3+1];
dst[(w + h * dst_w)*4+2] = src[(j+i*src_w)*3+0];
dst[(w + h * dst_w)*4+3] = 0;
}
}
}
void draw(char *rgb_out, const char *rgb, int w, int h)
{
int i = 0;
int idx = 0;
for (i = 0;i < w*h*4; i += 4)
{
rgb_out[i + 0] = rgb[idx+2];
rgb_out[i + 1] = rgb[idx+1];
rgb_out[i + 2] = rgb[idx+0];
rgb_out[i + 3] = 0;
idx+=3;
}
return;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。